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


相关文章
|
1月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
139 26
|
3月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
3月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
3月前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
89 6
|
3月前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
226 4
|
缓存 Java Spring
Spring 获取单例流程(三)
读完这篇文章你将会收获到 • Spring 何时将 bean 加入到第三级缓存和第一级缓存中 • Spring 何时回调各种 Aware 接口、BeanPostProcessor 、InitializingBean 等
138 0
|
缓存 Java Spring
Spring 获取单例流程(二)
读完这篇文章你将会收获到 • Spring 中 prototype 类型的 bean 如何做循环依赖检测 • Spring 中 singleton 类型的 bean 如何做循环依赖检测
91 0
|
XML 缓存 Java
Spring 获取单例流程(一)
读完这篇文章你将会收获到 • 在 getBean 方法中, Spring 处理别名以及 factoryBean 的 name • Spring 如何从多级缓存中根据 beanName 获取 bean • Spring 如何处理用户获取普通 bean 和 factoryBean
263 0
|
1天前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
96 79
|
23天前
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
75 12