Spring的 bean有5种作用域分别是:singleton、prototype、request、session和globalSession
简单介绍:
spring 起初的版本只有singleton,也就是是否是单例模式。
因为平时使用SPRING MVC开发的时候比较多,有必要了解清楚怎么去调用这几种作用域。
1,定义不同作用域的java类
@Component @Scope( "session") public class SessionObj { } @Component @Scope( "request") public class RequestObj { } @Component @Scope( "prototype") public class PrototypeObj { } @Component @Scope( "singleton") public class SingletonObj { }
2,注入到controller,由于controller是单例的,因此必须通过实现ApplicationContextAware接口,直接从容器中取出对象。
因此测试的controller是:
@Controller public class IndexController implements ApplicationContextAware { private RequestObj RequestObj; private SessionObj SessionObj; private PrototypeObj PrototypeObj; private SingletonObj SingletonObj; private ApplicationContext applicationContext; @RequestMapping("/") @ResponseBody public String index() { print(); return "Welcome"; } public void print() { System.out.println("first time singleton is :" + getSingletonObj()); System.out.println("second time singleton is :" + getSingletonObj()); System.out.println("first time prototype is :" + getPrototypeObj()); System.out.println("second time prototype is :" + getPrototypeObj()); System.out.println("first time request is :" + getRequestObj()); System.out.println("second time request is :" + getRequestObj()); System.out.println("first time session is :" + getSessionObj()); System.out.println("second time session is :" + getSessionObj()); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public RequestObj getRequestObj() { return applicationContext.getBean(RequestObj.class); } public void setRequestObj(RequestObj requestObj) { RequestObj = requestObj; } public SessionObj getSessionObj() { return applicationContext.getBean(SessionObj.class); } public void setSessionObj(SessionObj sessionObj) { SessionObj = sessionObj; } public PrototypeObj getPrototypeObj() { return applicationContext.getBean(PrototypeObj.class); } public void setPrototypeObj(PrototypeObj prototypeObj) { PrototypeObj = prototypeObj; } public SingletonObj getSingletonObj() { return applicationContext.getBean(SingletonObj.class); } public void setSingletonObj(SingletonObj singletonObj) { SingletonObj = singletonObj; } }
3,运行结果:
//使用chrome第一次打印数据: first time singleton is :com.fb.po.SingletonObj@1e3223e second time singleton is :com.fb.po.SingletonObj@1e3223e first time prototype is :com.fb.po.PrototypeObj@3e683f second time prototype is :com.fb.po.PrototypeObj@12e18d7 first time request is :com.fb.po.RequestObj@1d45706 second time request is :com.fb.po.RequestObj@1d45706 first time session is :com.fb.po.SessionObj@9a6b2e second time session is :com.fb.po.SessionObj@9a6b2e //使用chrome打印第二次数据 first time singleton is :com.fb.po.SingletonObj@1e3223e second time singleton is :com.fb.po.SingletonObj@1e3223e first time prototype is :com.fb.po.PrototypeObj@122e5be second time prototype is :com.fb.po.PrototypeObj@192add first time request is :com.fb.po.RequestObj@4d1b6c second time request is :com.fb.po.RequestObj@4d1b6c first time session is :com.fb.po.SessionObj@9a6b2e second time session is :com.fb.po.SessionObj@9a6b2e //使用IE打印第三次数据 first time singleton is :com.fb.po.SingletonObj@1e3223e second time singleton is :com.fb.po.SingletonObj@1e3223e first time prototype is :com.fb.po.PrototypeObj@10f1ecb second time prototype is :com.fb.po.PrototypeObj@1aeb990 first time request is :com.fb.po.RequestObj@18a1e7 second time request is :com.fb.po.RequestObj@18a1e7 first time session is :com.fb.po.SessionObj@12d5c55 second time session is :com.fb.po.SessionObj@12d5c55
4,结果分析:
从结果来看,单例的bean的三次的数据都是打印一样的(默认的bean的级别就是单例);
prototype的bean每次的数据都是不一样的,每次请求的时候调用两次结果都不一样。
request的bean在每次request的时候都不一致,但是同一次request返回的数据是一致的。
session的bean在前两次结果一致,最后一次数据不一致,和session的节奏是一致的。
5,欠缺
网络上说必需配置
<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>
但是没配置也好使……好奇……
最后一种作用域是适用于portlet,没试验,据说是在多个session之间可以共享,效果等同于全局变量。
感谢朴老师,我们有了另外一种测试方式
测试代码
@Controller @Scope("prototype") public class SecondController { @Autowired private RequestObj RequestObj; @Autowired private SessionObj SessionObj; @Autowired private PrototypeObj PrototypeObj; @Autowired private SingletonObj SingletonObj; @RequestMapping("/test") @ResponseBody public String index() { print(); return "Welcome"; } public void print() { System.out.println("first time singleton is :" + SingletonObj); System.out.println("second time singleton is :" + SingletonObj); System.out.println("first time prototype is :" + PrototypeObj); System.out.println("second time prototype is :" + PrototypeObj); System.out.println("first time request is :" + RequestObj); System.out.println("second time request is :" + RequestObj); System.out.println("first time session is :" + SessionObj); System.out.println("second time session is :" + SessionObj); } }
打印的结果是:
first time singleton is :com.fb.po.SingletonObj@83ca19 second time singleton is :com.fb.po.SingletonObj@83ca19 first time prototype is :com.fb.po.PrototypeObj@4961d6 second time prototype is :com.fb.po.PrototypeObj@4961d6 first time request is :com.fb.po.RequestObj@1b6467f second time request is :com.fb.po.RequestObj@1b6467f first time session is :com.fb.po.SessionObj@1ce5037 second time session is :com.fb.po.SessionObj@1ce5037 first time singleton is :com.fb.po.SingletonObj@83ca19 second time singleton is :com.fb.po.SingletonObj@83ca19 first time prototype is :com.fb.po.PrototypeObj@1089e03 second time prototype is :com.fb.po.PrototypeObj@1089e03 first time request is :com.fb.po.RequestObj@be12fc second time request is :com.fb.po.RequestObj@be12fc first time session is :com.fb.po.SessionObj@1ce5037 second time session is :com.fb.po.SessionObj@1ce5037 first time singleton is :com.fb.po.SingletonObj@83ca19 second time singleton is :com.fb.po.SingletonObj@83ca19 first time prototype is :com.fb.po.PrototypeObj@a7b674 second time prototype is :com.fb.po.PrototypeObj@a7b674 first time request is :com.fb.po.RequestObj@bb9ce2 second time request is :com.fb.po.RequestObj@bb9ce2 first time session is :com.fb.po.SessionObj@138ea04 second time session is :com.fb.po.SessionObj@138ea04
结果分析:
singleton , request 和session结果都是上面一致,但是prototype结果是和request效果一致的。所以如果要拿到prototype类型的数据的话,应该每次需要都去容器中去拿,而不是注入。
另,现在开发应用大多数都是无状态的,所以单例多线程是比较好的实现方式,多例的比较有利于保存状态,完全没必要。不过试验JVM垃圾回收,这不就是传说中朝生夕灭的对象吗。
参考http://haohaoxuexi.iteye.com/blog/1190526
相关推荐
Spring 的bean的作用域总结,详细的总结了 Spring 的bean的作用域
Spring Bean 的作用域之间有什么区别:Bean的作用域: 可以通过scope 属性来指定bean的作用域 ①singleton: 默认值。当IOC容器
spring bean 的作用域(scope), SPringle bean的作用域
讲解了spring的6种作用域:singleton(单例)、non-singleton(也称 prototype),Spring2.0以后,增加了session、request、global session三种专用于Web应用程序上下文的Bean
JSP 中Spring Bean 的作用域详解 Bean元素有一个scope属性,用于定义Bean的作用域,该属性有如下五个值: 1>singleton: 单例模式,在整个spring IOC容器中,单例模式作用域的Bean都将只生成一个实例。一般Spring...
NULL 博文链接:https://huangminwen.iteye.com/blog/1486717
主要介绍了Spring实战之Bean的作用域request用法,结合实例形式分析了spring中Bean的request作用域相关使用技巧与操作注意事项,需要的朋友可以参考下
详解Spring中bean的作用域,一级对action的管理方式,方便对spring有一个深入的了解
如果bean的作用域的属性被声明为 singleton, 那么Spring Ioc容器只会创建一个共享的bean实例。对于所有的bean请求,只要id与该bean定义的相匹配,那么Spring在每次需要时都返回同一个bean实例。 Singleton是单例...
主要介绍了Spring实战之Bean的作用域singleton和prototype用法,结合实例形式分析了Bean的作用域singleton和prototype相关使用方法及操作注意事项,需要的朋友可以参考下
* * * * Bean的作用域 作用域的种类 Spring 4.3中为Bean的实例定义了7种作用域,如下表所示: 注意:在上表7种作用域中,singleton和prototype是最常用的两种作用域。 在Spring配置文件中,可以使用<bean>元素的...
01.Spring Bean的作用域代码
JSP 中Spring Bean 的作用域详解.docx
Spring容器中Bean的作用域编程开发技术共3页.pdf.zip
NULL 博文链接:https://cici9898-007.iteye.com/blog/1407695
主要给大家介绍了Spring中Bean的生命周期和作用域及实现方式的相关资料,文中介绍的非常详细,对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
07_SSM面试题_Spring Bean的作用域之间有什么区别
NULL 博文链接:https://moshow.iteye.com/blog/1607598
使用了ApplicationContextAware接口,获取spring管理的bean; 多项目整合夸spring容器获取bean的实现方式。
主要介绍了浅谈Spring中Bean的作用域、生命周期,具有一定借鉴价值,需要的朋友可以参考下