-
bean的作用域一共有 4种
(1)单例: 整个应用中,只创建一个bean的实例(默认)
(2)原型: 每次注入或者通过应用上下文获取时,都创建一个新实例(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
(3)会话session: 为每个会话创建一个bean实例(WebApplicationContext.SCOPE_SESSION)
(4)请求request: 为每个请求创建一个bean实例(WebApplicationContext.SCOPE_REQUEST)
-
单例是默认的bean的作用域
-
Java Config使用 @Scope 配置作用域
与@Bean合用
示例
@Configuration public class ExplicitConfig { @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public Notepad notepad() { return new Notepad(); } @Bean public UniqueThing unique() { return new UniqueThing(); } }
-
Xml使用 scope属性
示例
<bean class="com.myapp.Notepad" scope="prototype" />
-
session和requestd作用域代理
(1)场景: 购物车ShoppingCart是一个session bean,而StoreService是一个单例 bean。StoreService由于是单例,所以在应用上下文加载时就会被创建,此时还没有ShoppingCart实例(因为有session来的时候才创建);另外StoreService也不应该和某个具体的ShoppingCart绑定,而是应该处理当前会话所使用的ShoppingCart实例
(2)解决方法:
不将真正的ShoppingCart实例注入到StoreService,而是将__一个__ShoppingCart bean的代理注入到StoreService,这个代理和原有bean的接口相同,需要调用时,代理会将调用委托给当前会话真正的bean实例
(3)Java Config设置作用域代理
@Scope中的value属性设置作用域范围,proxyMode设置代理模式
示例
@Component @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.INTERFACES) public class ShoppingCart { }
(4) Xml 设置作用域代理
首先在头部添加aop命名空间,然后使用<aop:scoped-proxy>元素 示例 <bean class="com.myapp.UniqueThing" id="uniqueThing" scope="session"> <aop:scoped-proxy proxy-target-class="false"/> </bean>
(5) INTERFACES和TARGET_CLASS
如果某个要设置作用域代理的bean是一个接口不是类的话,使用INTERFACES,这表明代理要实现该接口;
如果某个要设置作用域代理的bean是一个具体的类的话,使用TARGET_CLASS,这表明代理使用CGLib以生成目标类扩展的方式来生成基于类的代理
(6) request和session作用域的bean都会遇到这个问题,如果它们需要使用代理的话
网友评论