bean的作用域.
1.singleton作用域(针对无状态的bean)
只会创建一个共享的bean实例(相当于单例模式)。当有该bean实例的后续请求和引用都将返回被缓存的对象实例。
配置<bean id="test" class="test.Test" scope="singleton">
2.prototype作用域(针对有状态的bean)
每次请求该类型的bean都会创建一个新的bean实例(相当于以前的new一个对象)。
配置<bean id="test" class="test.Test" scope="prototype">
3.其他作用域(request,session,global session, application)
在使用之前需要在web.xml文件中配置
servlet 2.4之前版本配置如下:
<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>
servlet 2.4之后版本配置如下:
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
3.1 request作用域
配置<bean id="login" class="test.Login" scope="request">
针对每个http请求都会创建一个新的login实例,且该实例仅在当前请求内有效,而login实例彼此之间又相互独立,因此可放心更改所创建bean的内部状态。当请求处理结束,这些bean也会被销毁。
3.2 session作用域
配置<bean id="login" class="test.Login" scope="session">
和request类似
3.3 global session作用域
配置<bean id="login" class="test.Login" scope="globalSession"/>
与session类似,但是仅用于基于portlet的web应用程序。global session会被组成web应用程序的所有模块共享。
如果你使用基于servlet的web应用,且使用标准的session作用域定义若干个global session作用域的bean并不会引起什么错误。
3.4 application作用域
配置<bean id="appPreferences" class="com.foo.AppPreferences" scope="application"/>
注:在使用上述4个作用域注入的时候要加上<aop:scoped-proxy/>
例如:<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
解释:userManager是一个singleton bean,所以它只会被注入一次。如果不加<aop:scoped-proxy/>,userPreferences bean也只会被注入一次,所以之后调用的也都将是同一个userPreferences实例,这与我们使用session作用域的初衷相违背。
4.自定义作用域
我们可以自定义作用域。甚至可以重新定义现有作用域(只是不提倡这么做)
步骤:
a 声明你的作用域,实现org.springframework.beans.factory.config.Scope接口,编写自定义的scope的实现;
要实现四个方法 Object get(String name, ObjectFactory objectFactory)获取一个该作用域实例,如果它不存在,则该方法返回一个新的绑定作用域的实例
Object remove(String name)删除bean实例
void registerDestructionCallback(String name, Runnable destructionCallback)当某个具体的bean实例被销毁的时候调用
String getConversationId()获取一个该作用域的唯一标识码
b 使用void registerScope(String scopeName, Scope scope);方法告诉容器你声明的作用域该方法在ConfigurableBeanFactory接口中声的 (AbstractBeanFactory是实现了ConfigurableBeanFactory接口中registerScope方法的一个子类)。
举例: Scope threadScope = new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);第一参数是作用域名称,与prototype,singleton一样。第二参数是scope 对象实例
然后你就可以使用了<bean id="..." class="..." scope="thread">