spring bean的作用域之间有什么区别

Spring的 bean有5种作用域分别是:singleton、prototype、request、session和globalSession

简单介绍:

spring 起初的版本只有singleton,也就是是否是单例模式。

作用域包括:
singleton
全局只有一个实例
prototype
每次调用产生一个新的实例
在web使用的时候还有三个作用域,但是必须在web.xml中注册一个RequestContextListener , 目的是为了设置每次请求开始和结束都可以使spring得到相应的事件。
request
每次请求产生一个bean
session
每个用户session可以产生一个新的bean,不同用户之间的bean互相不影响
globalSession
作用和session类似,只是使用portlet的时候使用。
测试用例

因为平时使用SPRING MVC开发的时候比较多,有必要了解清楚怎么去调用这几种作用域。

1,定义不同作用域的java类

 

 

Java代码   收藏代码
  1. @Component  
  2. @Scope"session")  
  3. public class SessionObj {  
  4.   
  5. }  
  6. @Component  
  7. @Scope"request")  
  8. public class RequestObj {  
  9.   
  10. }  
  11. @Component  
  12. @Scope"prototype")  
  13. public class PrototypeObj {  
  14.   
  15. }  
  16. @Component  
  17. @Scope"singleton")  
  18. public class SingletonObj {  
  19.   
  20. }  

 2,注入到controller,由于controller是单例的,因此必须通过实现ApplicationContextAware接口,直接从容器中取出对象。

 

因此测试的controller是:

 

Java代码   收藏代码
  1. @Controller  
  2. public class IndexController implements ApplicationContextAware {  
  3.   
  4.     private RequestObj RequestObj;  
  5.   
  6.     private SessionObj SessionObj;  
  7.   
  8.     private PrototypeObj PrototypeObj;  
  9.   
  10.     private SingletonObj SingletonObj;  
  11.   
  12.     private ApplicationContext applicationContext;  
  13.   
  14.     @RequestMapping("/")  
  15.     @ResponseBody  
  16.     public String index() {  
  17.         print();  
  18.         return "Welcome";  
  19.     }  
  20.   
  21.     public void print() {  
  22.         System.out.println("first  time singleton is :" + getSingletonObj());  
  23.         System.out.println("second time singleton is :" + getSingletonObj());  
  24.   
  25.         System.out.println("first  time prototype is :" + getPrototypeObj());  
  26.         System.out.println("second time prototype is :" + getPrototypeObj());  
  27.   
  28.         System.out.println("first  time request is :" + getRequestObj());  
  29.         System.out.println("second time request is :" + getRequestObj());  
  30.   
  31.         System.out.println("first  time session is :" + getSessionObj());  
  32.         System.out.println("second time session is :" + getSessionObj());  
  33.     }  
  34.   
  35.     @Override  
  36.     public void setApplicationContext(ApplicationContext applicationContext)  
  37.             throws BeansException {  
  38.         this.applicationContext = applicationContext;  
  39.     }  
  40.   
  41.     public RequestObj getRequestObj() {  
  42.         return applicationContext.getBean(RequestObj.class);  
  43.     }  
  44.   
  45.     public void setRequestObj(RequestObj requestObj) {  
  46.         RequestObj = requestObj;  
  47.     }  
  48.   
  49.     public SessionObj getSessionObj() {  
  50.         return applicationContext.getBean(SessionObj.class);  
  51.     }  
  52.   
  53.     public void setSessionObj(SessionObj sessionObj) {  
  54.         SessionObj = sessionObj;  
  55.     }  
  56.   
  57.     public PrototypeObj getPrototypeObj() {  
  58.         return applicationContext.getBean(PrototypeObj.class);  
  59.     }  
  60.   
  61.     public void setPrototypeObj(PrototypeObj prototypeObj) {  
  62.         PrototypeObj = prototypeObj;  
  63.     }  
  64.   
  65.     public SingletonObj getSingletonObj() {  
  66.         return applicationContext.getBean(SingletonObj.class);  
  67.     }  
  68.   
  69.     public void setSingletonObj(SingletonObj singletonObj) {  
  70.         SingletonObj = singletonObj;  
  71.     }  
  72.   
  73. }  

 

 

3,运行结果:

 

Java代码   收藏代码
  1. //使用chrome第一次打印数据:  
  2. first  time singleton is :com.fb.po.SingletonObj@1e3223e  
  3. second time singleton is :com.fb.po.SingletonObj@1e3223e  
  4. first  time prototype is :com.fb.po.PrototypeObj@3e683f  
  5. second time prototype is :com.fb.po.PrototypeObj@12e18d7  
  6. first  time request is :com.fb.po.RequestObj@1d45706  
  7. second time request is :com.fb.po.RequestObj@1d45706  
  8. first  time session is :com.fb.po.SessionObj@9a6b2e  
  9. second time session is :com.fb.po.SessionObj@9a6b2e  
  10.   
  11.   
  12.   
  13. //使用chrome打印第二次数据  
  14. first  time singleton is :com.fb.po.SingletonObj@1e3223e  
  15. second time singleton is :com.fb.po.SingletonObj@1e3223e  
  16. first  time prototype is :com.fb.po.PrototypeObj@122e5be  
  17. second time prototype is :com.fb.po.PrototypeObj@192add  
  18. first  time request is :com.fb.po.RequestObj@4d1b6c  
  19. second time request is :com.fb.po.RequestObj@4d1b6c  
  20. first  time session is :com.fb.po.SessionObj@9a6b2e  
  21. second time session is :com.fb.po.SessionObj@9a6b2e  
  22.   
  23.   
  24.   
  25. //使用IE打印第三次数据  
  26. first  time singleton is :com.fb.po.SingletonObj@1e3223e  
  27. second time singleton is :com.fb.po.SingletonObj@1e3223e  
  28. first  time prototype is :com.fb.po.PrototypeObj@10f1ecb  
  29. second time prototype is :com.fb.po.PrototypeObj@1aeb990  
  30. first  time request is :com.fb.po.RequestObj@18a1e7  
  31. second time request is :com.fb.po.RequestObj@18a1e7  
  32. first  time session is :com.fb.po.SessionObj@12d5c55  
  33. second time session is :com.fb.po.SessionObj@12d5c55  

 

 

4,结果分析:

从结果来看,单例的bean的三次的数据都是打印一样的(默认的bean的级别就是单例);

prototype的bean每次的数据都是不一样的,每次请求的时候调用两次结果都不一样。

request的bean在每次request的时候都不一致,但是同一次request返回的数据是一致的。

session的bean在前两次结果一致,最后一次数据不一致,和session的节奏是一致的。

 

5,欠缺

 

网络上说必需配置

Xml代码   收藏代码
  1. <listener>   
  2. <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>   
  3. </listener>   

 但是没配置也好使……好奇……

 

最后一种作用域是适用于portlet,没试验,据说是在多个session之间可以共享,效果等同于全局变量。

 

 

 

感谢朴老师,我们有了另外一种测试方式

测试代码

 

Java代码   收藏代码
  1. @Controller  
  2. @Scope("prototype")  
  3. public class SecondController {  
  4.   
  5.     @Autowired  
  6.     private RequestObj RequestObj;  
  7.   
  8.     @Autowired  
  9.     private SessionObj SessionObj;  
  10.   
  11.     @Autowired  
  12.     private PrototypeObj PrototypeObj;  
  13.   
  14.     @Autowired  
  15.     private SingletonObj SingletonObj;  
  16.   
  17.     @RequestMapping("/test")  
  18.     @ResponseBody  
  19.     public String index() {  
  20.         print();  
  21.         return "Welcome";  
  22.     }  
  23.   
  24.     public void print() {  
  25.         System.out.println("first  time singleton is :" + SingletonObj);  
  26.         System.out.println("second time singleton is :" + SingletonObj);  
  27.   
  28.         System.out.println("first  time prototype is :" + PrototypeObj);  
  29.         System.out.println("second time prototype is :" + PrototypeObj);  
  30.   
  31.         System.out.println("first  time request is :" + RequestObj);  
  32.         System.out.println("second time request is :" + RequestObj);  
  33.   
  34.         System.out.println("first  time session is :" + SessionObj);  
  35.         System.out.println("second time session is :" + SessionObj);  
  36.     }  
  37.   
  38. }  

 

打印的结果是:

Java代码   收藏代码
  1. first  time singleton is :com.fb.po.SingletonObj@83ca19  
  2. second time singleton is :com.fb.po.SingletonObj@83ca19  
  3. first  time prototype is :com.fb.po.PrototypeObj@4961d6  
  4. second time prototype is :com.fb.po.PrototypeObj@4961d6  
  5. first  time request is :com.fb.po.RequestObj@1b6467f  
  6. second time request is :com.fb.po.RequestObj@1b6467f  
  7. first  time session is :com.fb.po.SessionObj@1ce5037  
  8. second time session is :com.fb.po.SessionObj@1ce5037  
  9.   
  10.   
  11. first  time singleton is :com.fb.po.SingletonObj@83ca19  
  12. second time singleton is :com.fb.po.SingletonObj@83ca19  
  13. first  time prototype is :com.fb.po.PrototypeObj@1089e03  
  14. second time prototype is :com.fb.po.PrototypeObj@1089e03  
  15. first  time request is :com.fb.po.RequestObj@be12fc  
  16. second time request is :com.fb.po.RequestObj@be12fc  
  17. first  time session is :com.fb.po.SessionObj@1ce5037  
  18. second time session is :com.fb.po.SessionObj@1ce5037  
  19.   
  20.   
  21. first  time singleton is :com.fb.po.SingletonObj@83ca19  
  22. second time singleton is :com.fb.po.SingletonObj@83ca19  
  23. first  time prototype is :com.fb.po.PrototypeObj@a7b674  
  24. second time prototype is :com.fb.po.PrototypeObj@a7b674  
  25. first  time request is :com.fb.po.RequestObj@bb9ce2  
  26. second time request is :com.fb.po.RequestObj@bb9ce2  
  27. first  time session is :com.fb.po.SessionObj@138ea04  
  28. second time session is :com.fb.po.SessionObj@138ea04  

 

 

结果分析:

singleton , request 和session结果都是上面一致,但是prototype结果是和request效果一致的。所以如果要拿到prototype类型的数据的话,应该每次需要都去容器中去拿,而不是注入。

 

 

另,现在开发应用大多数都是无状态的,所以单例多线程是比较好的实现方式,多例的比较有利于保存状态,完全没必要。不过试验JVM垃圾回收,这不就是传说中朝生夕灭的对象吗。

参考http://haohaoxuexi.iteye.com/blog/1190526

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值