我们不仅可以控制注入到bean中的各种依赖和配置值,还可以控制该bean的scope,而不必在javaclass级定义scope。Spring支持5种scope(有3种只能用在基于web的Spring ApplicationContext)。
(1)Singleton:Spring的默认scope。Spring的IOC容器中只会存在一个该bean的实例。所有对bean的请求,只要id与该bean定义匹配,则只会返回bean的同一实例,即每次拿到的对象都是引用同一地址的对象。
<bean id="accountService" class="com.foo.DefaultAccountService"/>
<!-- singleton scope is the default-->
<bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/>
<!-- preserved for backward compatibility -->
<bean id="accountService" class="com.foo.DefaultAccountService" singleton="true"/>
(2)Prototype:每次对该bean请求时都会创建一个新的bean实例,即每次拿到的对象都是引用不同地址的对象。据经验,对所有有状态的bean应该使用prototype,而对无状态的bean则应该使用singleton。
<bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/>
<!-- preserved for backward compatibility -->
<bean id="accountService" class="com.foo.DefaultAccountService" singleton="false"/>
【 Spring不能对一个prototype bean的整个生命周期负责,spring容器在初始化、配置、装配完一个prototype实例后,将bean返回给调用者,调用者负责bean的后续生命的管理,Spring不再管理这些bean的生命周期。
任一种scope,容器都会呼叫所有bean的初始化生命周期callback方法,而prototype不会呼叫任何配置好的Destroy生命周期callback方法。
】
其他的scope(request、session、globalsession)仅在基于web的应用中使用(如XmlWebApplicationContext),如果在普通的Spring IoC容器中(如XmlBeanFactory、ClassPathXmlApplicationContext),尝试使用,则会得到一个IllegalStateException(未知的bean scope)。
要使用这3个bean之前,还要做少量的初始配置:
<1> 如果使用的是Servlet2.4及以上的web容器,只需要在web.xml文件加ContextListener。
<web-app>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app>
<2> 如果是2.4以前的web容器,则要使用一个javax.servlet.Filter实现。
<web-app>
..
<filter>
<filter-name>requestContextFilter</filter-name> <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern> <!—这个项目的所有请求都会捕捉
</filter-mapping>
...
</web-app>
(3)request:表示针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTPrequest内有效。因此可以根据需要放心地更改所建实例的内部状态,而其他请求中创建的实例将不会看到这些特定于某个请求的状态变化。当处理请求结束,request scope的bean实例将被销毁。
<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>
(4)session:表示针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTPsession内有效,与request scope一样,可以根据需要放心更改实例内部状态,当HTTP session最终被废弃的时候,在该scope内的bean也会被废弃。
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
(5)global session:作用域类似于HTTP session,不过仅仅在基于portlet的web应用中才有意义。如果在基于Servlet的web应用中定义一个或多个具有global session作用域的bean,系统会使用标准的HTTP session scope,不会出错。
<bean id="userPreferences" class="com.foo.UserPreferences" scope="globalSession"/>