`
newleague
  • 浏览: 1492363 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

Spring中单例bean访问非单例bean的第一种方式:方法注入

阅读更多

      方法注入在Spring中是很少用的,主要应用是, 对象中可能定义了一个受保护的抽象方法,而容器可能在运行时实现他以返回由容器查询得到的对象。

  方法注入的最好用途之一就是处理单态、无状态对象需要调用非单态、有状态或者非线程安全对象的情况。

  以前刚接触Spring时,如果在单例bean中调用非单例bean,只要把那个非单例bean 的singleton设置为false就可以了。其实不然,大家想,我们创建了一个单例对象,在此单例对象中所用到的其它bean也只会创建一次——(大多数情况是这样的,当然我们要解决的就是这个问题)。所以说,单纯的把非单例bean的属性singleton设为false是解决不了的。此时就是方法注入大显身手的时候了。

  下面的例子是单例调用单例的情况:我们在service层调用DAO层

/**
*@authorzhu国辉
*/
package com.zgh.spring.dao;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
*记住一定要引入org.springframework.orm.(hibernate3).support.HibernateDaoSupport
*也就是此类的父类.
*@authorzhu国辉
*
*/
public class UserLoginDao extends HibernateDaoSupport implements IUserLoginDao{
  inti=0;
  public List getUser(Stringusername,Stringpassword){
    System.out.println("i="+(++i));
    System.out.println(username+":"+password);
    List users=getHibernateTemplate().find("from User u where username=? and password=?",newObject[]{username,password});
    return users;
  }
}

 

 

为了查看效果,我们在DAO中声明了一个成员变量(变成有状态bean)

  下面是Service层:

/**
*@authorzhu国辉
*/
package com.zgh.spring.service;
import java.util.List;
import com.zgh.spring.dao.IUserLoginDao;;
public class UserLoginService implements IUserLoginService{
  private IUserLoginDao userLoginDao;
  public void setUserLoginDao(IUserLoginDao userLoginDao){
    this.userLoginDao=userLoginDao;
  }
  public List getUser(String username,String password){
    return userLoginDao.getUser(username,password);
  }
}

  这是最基本的形式了,单例调用单例,每次程序运行时,DAO里的i都会+1, Spring的配置文件如下:

  <!--====================DAO=======================-->
  <bean id="userLoginDao" class="com.zgh.spring.dao.UserLoginDao">
    <property name="sessionFactory">
      <ref local="mySessionFactory"/>
    </property>
  </bean>
  <!--====================Service=======================-->
  <bean id="userLoginService" class="com.zgh.spring.service.UserLoginService">
    <property name="userLoginDao">
      <ref local="userLoginDao"/>
    </property>
  </bean>

 

那么我们简单的把userLoginDao中添加属性singleton="false",如下:

  <bean id="userLoginDao" class="com.zgh.spring.dao.UserLoginDao" singleton="false">
    <property name="sessionFactory">
      <ref local="mySessionFactory"/>
    </property>
  </bean>

  我们再运行,i打印出来的还是每被访问一次就+1,也就是说只靠singleton="false"是不行的,下面我们进行正题:

  我们选修改一下 Service:

/**
*@authorzhu国辉
*/
package com.zgh.spring.service;
import java.util.List;
import com.zgh.spring.dao.IUserLoginDao;;
public abstract class UserLoginService implements IUserLoginService{
  protected abstract IUserLoginDao getUserLoginDao();
  public List getUser(String username,String password){
    return getUserLoginDao().getUser(username,password);
  }
}

  看看我们都做了什么事:把类声明成abstract,定义一个抽象方法:getUserLoginDao();在使用IUserLoginDao的地方直接使用getUserLoginDao()方法。DAO层没有什么变化,下面看一下XML配置文件:

  <!--====================DAO=======================-->
  <bean id="userLoginDao" class="com.zgh.spring.dao.UserLoginDao" singleton="false">
    <property name="sessionFactory">
      <ref local="mySessionFactory"/>
    </property>
  </bean>
  <!--====================Service=======================-->
  <bean id="userLoginService" class="com.zgh.spring.service.UserLoginService">
    <lookup-method name="getUserLoginDao" bean="userLoginDao"/>
  </bean>

 

  大功告成:运行结果看看,第次i打印的结果都是1,也就是说每次都生成了新的UserLoginDao实例。在最后的这个XML中,我们先把DAO的属性singleton设置为false,然后在Service中用<lookup-method>配置他的依赖,name指定类中的抽象方法,bean指定要注入的类。如此而以。

 

分享到:
评论

相关推荐

    unity中涉及的三种单例模式

    在Unity游戏开发中,单例模式是一种常用的编程设计模式,它确保一个类只有一个实例,并提供一个全局访问点。这种模式在处理需要跨场景共享数据的情况时尤其有用,因为Unity的场景切换可能导致对象被销毁,而单例则...

    Java多线程编程环境中单例模式的实现

    单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式的应用非常广泛,特别是在资源管理、日志记录、数据库连接等方面。然而,在多线程环境中实现单例模式时,...

    JAVA中单例模式的几种实现方式.doc

    ### JAVA中单例模式的几种实现方式 #### 1. 线程非安全的基本实现方式 单例模式是设计模式中的一种常用形式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式可以通过多种方式来...

    浅谈Java中单例设计模式之构造方法私有化.pdf

    "浅谈Java中单例设计模式之构造方法私有化" 单例设计模式是 Java 中一种常用的设计模式,核心思想是将类的构造方法私有化,以控制实例化对象的产生。这种模式可以确保在程序中只有一个实例化对象存在,这对控制对象...

    java单例模式实例

    单例模式是软件设计模式中的一种经典模式,用于确保一个类只有一个实例,并提供一个全局访问点。在Java中,有多种实现单例模式的方法,每种都有其特点和适用场景。接下来,我们将深入探讨这些实现方式。 首先,我们...

    c++中单例模式对象的释放控制

    在C++编程领域,设计模式是解决特定问题的模板,其中单例模式(Singleton Pattern)是一种常用的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。然而,在C++中实现单例模式时,如何正确管理这个...

    基于php设计模式中单例模式的应用分析

    单例模式是软件设计模式中的一种,它的核心思想是确保某个类在整个应用程序中只有一个实例存在。在PHP中,单例模式常用于管理共享资源,如数据库连接或全局配置,以优化性能并提供统一的访问入口。 单例模式的实现...

    PHP中单例模式的使用场景与使用方法讲解

    单例模式主要有三种实现方式:懒汉式单例、饿汉式单例、登记式单例。懒汉式单例是延迟加载实例,只有在第一次调用时才初始化实例;饿汉式单例是在类加载时就完成了初始化,访问时不需要等待初始化;登记式单例是通过...

    OC单例模式讲解

    1. **双重检查锁定(Double-checked locking)**:这是一种常用的解决线程安全问题的方法,可以在不牺牲性能的情况下保证单例模式的线程安全。 2. **使用`@synchronized`关键字**:在获取实例的方法中使用 `@...

    Java中单例模式详解

    懒汉式单例的特点是在类第一次被使用时才创建实例,延迟加载,以节省资源。然而,非线程安全的懒汉式单例在多线程环境下可能导致多个实例的创建。上述代码中的`Singleton`类就是一个典型的懒汉式实现,但在多线程...

    学习SSM源码分析的一次实践,自己实现SSM框架

    在spring中最核心的就是IOC容器,默认采用的是通过单例的模式来进行管理我们注入到Ioc中的bean(当然我们也是可以修改成其他的模式,暂且不讨论),在spring中单例模式是采用注册的方式来实现的单例模式,所以我也是...

    android SQLite DBHelper 单例模式 实现

    android SQLite DBHelper 单例模式 实现 dbhelper=DBHelper.getInstance(this);

    Java实现多种单例模式

    这种方式延迟了单例对象的初始化,直到第一次被请求时。例如,`SingleInstance1.java`可能就实现了这种方式。代码通常包含一个私有构造函数,一个私有的静态单例对象和一个公共的静态获取单例的方法。这种方法在多...

    java 中单例模式饿汉式与懒汉式的对比

    java 中单例模式是保证一个类仅有一个实例,并提供一个访问它的全局访问点的设计模式。单例模式有以下特点:单例类只能有一个实例,单例类必须自己自己创建自己的唯一实例,单例类必须给所有其他对象提供这一实例。 ...

    Python中单例模式总结

    在Python编程中,单例模式是一种设计模式,它限制了类的实例化过程,确保一个类只有一个实例,并提供全局访问点。这种模式在需要频繁实例化然后销毁的对象,或者创建对象需要消耗大量资源的场景下非常有用,因为它...

    Kotlin中单例模式和Java的对比浅析

    Kotlin 中单例模式是指在应用程序中确保某个类仅有一个实例,并提供一个全局访问点的机制。单例模式是一种常用的设计模式,在 Java 和 Kotlin 中都有多种实现方式。下面我们将对比 Kotlin 中单例模式和 Java 中单例...

    单例模式实现mdi界面子窗体控制

    首先向关注过我这个系列...这立刻让我想到了最常用也是最简单最容易理解的一个设计模式 单例模式 何为 单例模式 ? 故名思议 即 让 类 永远都只能有一个实例。 由于 示例代码 比较简单 我也加了注释,这里就不在赘述

    Android应用正确的退出方式(单例模式)

    Android应用正确的退出方式(单例模式)

    singleton.zip单例的几种实现demo,

    在Java编程中,单例模式是一种常用的软件设计模式,它保证了类只有一个实例,并提供一个全局访问点。在"singleton.zip"压缩包中,我们可能会找到几种不同的Java单例实现方式的示例代码,包括饿汉式、懒汉式、反射...

Global site tag (gtag.js) - Google Analytics