spring定义了多种作用域,如下
单例(Singleton):在整个应用中,只会创建一个bean的实例
原型(Prototype):每次注入或者通过spring上下文获取的时候,都会创建一个新的bean实例
会话(Session):在web应用中,为每个会话创建一个bean实例
请求(Request):在web应用中,为每个请求创建一个bean实例
其中单例是默认的作用域
声明bean的作用域
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad{...}
xml配置
<bean id="notepad" class="com.myapp.Notepad" scope="prototype" />
1 使用会话和作用域
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)
publlic ShoppingCart cart(){....}
@Component
public class StoreService {
@Autowired
public void setShoppingcart(Shoppingcart shoppingcart){
this.shoppingcart = shoppingcart;
}
}
此时StoreService是一个单例的bean,会在Spring应用上下文加载的时候创建.当它创建的时候,Spring会试图将ShoppingCart bean注入到setShoppingCart()中.但是ShoppingCart是会话作用域的,此时并不存在.直到某个用户进入到系统创建会话之后,才会出现ShoppingCart实例.同时每个用户都会有一个ShoppingCart,我们并不想让spring注入某个固定的ShoppingCart实例,而是当StoreService在处理shoppingcart时,它使用的ShoppingCart刚好时当前会话的那一个.
spring并不会将实际的ShoppingCart bean注入到StoreService中,Spring会注入一个SpringCart bean的代理.这个代理会暴露与ShoppingCart相同的方法,代理会对其进行懒解析并将调用委托给会话作用域内真正的ShoppingCart bean.在上面代码中,proxyMode被设置成了ScopedProxyMode.INTERFACES,这表明这个代理要实现ShoppingCart接口,并将调用委托给实现bean.当ShoppingCart是接口时,这是可以的.但ShoppingCart是一个具体的bean时,spring就无法创建基于接口的代理了,此时就必须使用CGLib来生成基于类的代理bean,proxyMode属性就要设置为ScopedProxyMode.TARGET_CLASS.
2 在xml中声明作用域代理
<bean id="cart" class="com.myapp.ShoppingCart" scope="session">
<aop:scoped-proxy />
</bean>
aop:scoped-proxy 是与@Scope注解的proxyMode属性功能相同的Spring XML配置元素.他会告诉Spring为bean创建一个作用域代理.默认情况下,它会使用CGLib创建目标类的代理.但是我们也可以将proxy-target-class属性设置为false,此时它就会生成基于接口的代理.
<bean id="cart" class="com.myapp.ShoppingCart" scope="session">
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
说明:使用aop:scoped-proxy元素,需要在xml的配置中声明aop命名空间:
<?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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
...
</beans>