Spring中Bean的4大作用域
单例 Singleton
在整个应用中只创建一个bean实例,Spring中都bean默认都是单例都,也就是说不管你在任何地方,以任何方式注入,装配都是同一个Bean对象。 单例的Bean 初始化,和回收都是小成本,但是当我们都类是易变都时候,你会发现Bean很容易被污染。影响我们后续使用。
原型 Prototype
每次注入,或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。想要声明一个Prototype作用域 ,可以在Bean声明都时候指定@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 当然你也可以使用@Scope("prototype") 但是我认为前者较为安全,不易错。
同时你也可以在xml声明Bean的时候使用scope属性指定prototype
<bean id="ID值" class="全限定类名" scope="prototype" >
但是这种使用场景较少。
会话 Session
在Web应用中,每个会话创建一个bean实例,就会话域而言,有一个特别合适的例子,购物车Bean 。
声明Session域Bean的时候加上@Scope(value="WebApplicationContext.SCOPE_SESSION",proxyMode="ScopedProxyMode.INTERFACES")
你也可以使用中声明
<bean id="" class="" scope="session">
<aop:scoped-proxy proxy-target-class="false"> (使用aop的命名空间需要在XML配置中声明)
</bean>
相比之前的声明方式 多了一个proxyMode,我们详细介绍一下这个proxyMode 他是用来指定bean的代理方式(基于接口或者类)
他解决了session或者request注入到singleton时所产生的问题。singleton是从Spring上下午加载的时候创建,但是这时候ession和request还没有被创建,他们只有在第一次请求来的时候才会被创建,所以spring会代理,当调用的时候会委托真正的对象。
而proxyMode的值就是指定这个类是基于接口代理还是基于类代理CGLib。
@Scope(value="WebApplicationContext.SCOPE_SESSION",proxyMode="ScopedProxyMode.INTERFACES") 基于接口
@Scope(value="WebApplicationContext.SCOPE_SESSION",proxyMode="ScopedProxyMode.TARGET_CLASS") 基于类
<aop:scoped-proxy > 默认基于CGlib代理。 指定proxy-target-class="false"基于接口代理
请求 Request
在web应用中,为每个请求创建一个bean实例,
声明方式与Session一样 指定值为
@Scope(value="WebApplicationContext.SCOPE_REQUEST",proxyMode="ScopedProxyMode.INTERFACES")