java Spring bean作用域
1. Singleton作用域
当一个bean的作用域为singleton, 那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
换言之,当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。
2. Prototype作用域
Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()
方法)时都会创建一个新的bean实例。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
下面几个作用域是web里面的,需要添加配置
1. 初始化web配置
<web-app> ... <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> ... </web-app>
2. Request作用域
<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>
针对每次HTTP请求,Spring容器会根据loginAction
bean定义创建一个全新的LoginAction
bean实例, 且该loginAction
bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例的内部状态, 而其他请求中根据loginAction
bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。 当处理请求结束,request作用域的bean实例将被销毁。
3. Session作用域
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
针对某个HTTP Session
,Spring容器会根据userPreferences
bean定义创建一个全新的userPreferences
bean实例, 且该userPreferences
bean仅在当前HTTP Session
内有效。 与request作用域
一样,你可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session
中根据userPreferences
创建的实例, 将不会看到这些特定于某个HTTP Session
的状态变化。 当HTTP Session
最终被废弃的时候,在该HTTP Session
作用域内的bean也会被废弃掉。
4. global session作用域
<bean id="userPreferences" class="com.foo.UserPreferences" scope="globalSession"/>
global session
作用域类似于标准的HTTP Session
作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session
的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。在global session
作用域中定义的bean被限定于全局portlet Session
的生命周期范围内。
请注意,假如你在编写一个标准的基于Servlet的web应用,并且定义了一个或多个具有global session
作用域的bean,系统会使用标准的HTTP Session
作用域,并且不会引起任何错误。
4. 如果要将一个不同作用域的bean注入到另一个作用域的bean中,那么就需要用到代理注入
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> <!-- this next element effects the proxying of the surrounding bean --> <aop:scoped-proxy/> </bean> <!-- a singleton-scoped bean injected with a proxy to the above bean --> <bean id="userService" class="com.foo.SimpleUserService"> <!-- a reference to the proxied 'userPreferences' bean --> <property name="userPreferences" ref="userPreferences"/> </bean>
注意:<aop:scoped-proxy/>
不能和作用域为singleton
或prototype
的bean一起使用。为singleton bean创建一个scoped proxy将抛出BeanCreationException
异常。
自定义作用域:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> <property name="scopes"> <map> <entry key="thread"> <bean class="com.foo.ThreadScope"/> </entry> </map> </property> </bean> <bean id="bar" class="x.y.Bar" scope="thread"> <property name="name" value="Rick"/> <aop:scoped-proxy/> </bean> <bean id="foo" class="x.y.Foo"> <property name="bar" ref="bar"/> </bean> </beans>