天天看点

Spring Bean的作用域Spring中Bean的4大作用域

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")