Spring定义了多种作用域,可以基于这些作用域创建bean:
单例(Singleton):在整个应用中只创建bean的一个实例原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例会话(Session):在Web应用中,为每个会话创建一个bean实例请求(Rquest):在Web应用中,为每个请求创建一个bean实例例子:
@Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class Notepad {...} @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public Notepad notepad(){ return new Notepad(); } <bean id="notepad" class="com.myapp.Notepad" scope="prototype" />例子:
@Bean @Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES) public ShoppingCart cart() {...}假设Spring要将ShoppingCart bean注入到单例的StoreService中,则Spring并不会实际将ShoppingCart bean注入,而是创建一个代理。如果ShoppingCart是接口的话(最理想的代理方式),则代理会实现ShoppingCart接口,并将调用委托给实现bean,如果ShoppingCart是类,则以生成目标类扩展的方式创建代理,区别在于proxyMode属性的设置,如果是类则设置为ScopedProxyMode.TARGET_CLASS。同理,请求作用域也以作用域代理的方式进行注入。
作用域代理能够延迟注入请求和会话作用域的bean。
首先在XML顶部声明aop命名空间,在XML中声明会话和请求作用域的例子如下:
<bean id="cart" class="com.myapp.ShoppingCart" scope="session"> <aop:scoped-proxy /> </bean> <bean id="cart" class="com.myapp.ShoppingCart" scope="session"> <aop:scoped-proxy proxy-target-class="false" /> </bean>前者是生成目标类代理,后者是生成基于接口的代理。