Spring中单例bean访问非单例bean的两种方式

简介:

第一种方式:方法注入

方法注入在Spring中是很少用的,主要应用是, 对象中可能定义了一个受保护的抽象方法,而容器可能在运行时实现他以返回由容器查询得到的对象。
方法注入的最好用途之一就是处理单态、无状态对象需要调用非单态、有状态或者非线程安全对象的情况。

1
2
3
4
5
package  com.mzsx.spring.notsingleton;
public  interface  IUserDao {
  public  void  add();
  public  void  delete();
  public  void  load();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  com.mzsx.spring.notsingleton;
public  class  UserDaoImp  implements  IUserDao {
  @Override
  public  void  add() {
   System.out.println( "dao添加用户。。。。" );
  }
  @Override
  public  void  delete() {
   System.out.println( "dao***用户。。。。" );
  }
  @Override
  public  void  load() {
   System.out.println( "dao加载用户。。。。" );
  }
}
1
2
3
4
5
6
7
8
package  com.mzsx.spring.notsingleton;
public  abstract  class  UserService {
  protected  abstract   IUserDao getUserDao();
  
 
  public  void  add() {
   getUserDao().add();
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? xml  version = "1.0"  encoding = "UTF-8" ?>
 
< beans  xmlns="
http://www.springframework.org/schema/beans
"
 
        xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
"
 
        xsi:schemaLocation="
http://www.springframework.org/schema/beans
 
            
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
">
 
     < bean  id = "userDao"  class = "com.mzsx.spring.notsingleton.UserDaoImp"  scope = "prototype" ></ bean >
 
     < bean  id = "userService"  class = "com.mzsx.spring.notsingleton.UserService"  >
 
      < lookup-method  name = "getUserDao"  bean = "userDao"   /> 
 
     </ bean >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  com.mzsx.spring.notsingleton;
import  org.junit.Test;
import  org.springframework.beans.factory.BeanFactory;
import  org.springframework.context.support.ClassPathXmlApplicationContext;
public  class  TestMain {
  private  BeanFactory factory=  new  ClassPathXmlApplicationContext( "beans1.xml" );
  @Test
  public  void  notSingleton(){
   UserService users=(UserService)factory.getBean( "userService" );
   System.out.println(users.getUserDao());
   UserService users1=(UserService)factory.getBean( "userService" );
   System.out.println(users1.getUserDao());
   
  }
}

结果:

1
2
3
4
5
6
7
8
9
2014 - 6 - 3  22 : 00 : 10  org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
 
信息: Pre-instantiating singletons in 
org.springframework.beans.factory.support.DefaultListableBeanFactory @5bb966
: defining beans [userDao,userService]; root of factory hierarchy
 
com.mzsx.spring.notsingleton.UserDaoImp @caf6c1
 
com.mzsx.spring.notsingleton.UserDaoImp @10e35d5

需要使用cgLib。

第二种方式:ApplicationContextAware

1
2
3
4
5
package  com.mzsx.spring.notsingleton2;
public  interface  IUserDao {
  public  void  add();
  public  void  delete();
  public  void  load();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package  com.mzsx.spring.notsingleton2;
import  org.springframework.beans.BeansException;
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.ApplicationContextAware;
public  class  UserDaoImp  implements  IUserDao,ApplicationContextAware {
  private  ApplicationContext app;
  
  @Override
  public  void  add() {
   System.out.println((IUserDao)app.getBean( "userDao" ));
   System.out.println( "dao添加用户。。。。" );
  }
  @Override
  public  void  delete() {
   System.out.println( "dao***用户。。。。" );
  }
  @Override
  public  void  load() {
   System.out.println( "dao加载用户。。。。" );
  }
  @Override
  public  void  setApplicationContext(ApplicationContext app)
    throws  BeansException {
   // TODO Auto-generated method stub
   this .app=app;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
package  com.mzsx.spring.notsingleton2;
public   class  UserService {
  private  IUserDao userDao;
  public  IUserDao getUserDao() {
   return  userDao;
  }
  public  void  setUserDao(IUserDao userDao) {
   this .userDao = userDao;
  }
  public  void  add() {
   userDao.add();
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? xml  version = "1.0"  encoding = "UTF-8" ?>
 
< beans  xmlns="
http://www.springframework.org/schema/beans
"
 
        xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
"
 
        xsi:schemaLocation="
http://www.springframework.org/schema/beans
 
            
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
">
 
     < bean  id = "userDao"  class = "com.mzsx.spring.notsingleton2.UserDaoImp"  scope = "prototype" ></ bean >
 
     < bean  id = "userService"  class = "com.mzsx.spring.notsingleton2.UserService"  >
 
      < property  name = "userDao"  ref = "userDao" ></ property >
 
     </ bean >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  com.mzsx.spring.notsingleton2;
import  org.junit.Test;
import  org.springframework.beans.factory.BeanFactory;
import  org.springframework.context.support.ClassPathXmlApplicationContext;
public  class  TestMain {
  private  BeanFactory factory=  new  ClassPathXmlApplicationContext( "beans2.xml" );
  @Test
  public  void  notSingleton(){
   UserService users=(UserService)factory.getBean( "userService" );
   users.add();
   UserService users1=(UserService)factory.getBean( "userService" );
   users1.add();
   
  }
}


结果:d

1
2
3
4
5
6
7
8
9
10
11
12
13
2014 - 6 - 3  22 : 03 : 20  org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
 
信息: Pre-instantiating singletons in 
org.springframework.beans.factory.support.DefaultListableBeanFactory @1e903d5
: defining beans [userDao,userService]; root of factory hierarchy
 
com.mzsx.spring.notsingleton2.UserDaoImp @1554d32
 
dao添加用户。。。。
 
com.mzsx.spring.notsingleton2.UserDaoImp @13f136e
 
dao添加用户。。。。

 

ApplicationContextAware接口,此接口定义了一个方法setApplicationContext()方法,此方法在Spring初始化类以后,调用实现了ApplicationContextAware接口的类的setApplicationContext()方法,将自身的一个引用传递给此实例。

我们将这两种单例调用非单例的例子对比一下,不难看出,第一种方式:方法注入要好于第二种方式:实现接口。原因是,第二种方式与Spring绑定了。而第一种方式则没有这种情况,在Service中,我们根本看不出Spring的影子。

 

 


本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/1421705


相关文章
|
18天前
|
缓存 Java Spring
Spring 框架中 Bean 的生命周期
Spring 框架中 Bean 的生命周期
30 1
|
1月前
|
XML Java 开发者
Spring Boot中的bean注入方式和原理
Spring Boot中的bean注入方式和原理
44 0
|
2天前
|
Java 数据库连接 开发者
浅谈Spring的Bean生命周期
浅谈Spring的Bean生命周期
10 1
|
7天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
17 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
17天前
|
XML Java 程序员
作为Java程序员还不知道Spring中Bean创建过程和作用?
作为Java程序员还不知道Spring中Bean创建过程和作用?
12 0
|
22天前
|
XML 缓存 Java
天天用 Spring,bean 实例化原理你懂吗
天天用 Spring,bean 实例化原理你懂吗
17 0
|
1月前
|
Java Spring
Spring5深入浅出篇:bean的生命周期
Spring5深入浅出篇:bean的生命周期
|
缓存 Java Spring
Spring 获取单例流程(三)
读完这篇文章你将会收获到 • Spring 何时将 bean 加入到第三级缓存和第一级缓存中 • Spring 何时回调各种 Aware 接口、BeanPostProcessor 、InitializingBean 等
107 0
|
缓存 Java Spring
Spring 获取单例流程(二)
读完这篇文章你将会收获到 • Spring 中 prototype 类型的 bean 如何做循环依赖检测 • Spring 中 singleton 类型的 bean 如何做循环依赖检测
65 0
|
XML 缓存 Java
Spring 获取单例流程(一)
读完这篇文章你将会收获到 • 在 getBean 方法中, Spring 处理别名以及 factoryBean 的 name • Spring 如何从多级缓存中根据 beanName 获取 bean • Spring 如何处理用户获取普通 bean 和 factoryBean
201 0