SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-005-Bean的作用域@Scope、ProxyMode

一、

Spring的bean默认是单例的

But sometimes you may find yourself working with a mutable class that does main-
tain some state and therefore isn’t safe for reuse. In that case, declaring the class as a
singleton bean probably isn’t a good idea because that object can be tainted and cre-
ate unexpected problems when reused later.
Spring defines several scopes under which a bean can be created, including the
following:
 Singleton—One instance of the bean is created for the entire application.
 Prototype—One instance of the bean is created every time the bean is injected
into or retrieved from the Spring application context.
 Session—In a web application, one instance of the bean is created for each session.
 Request—In a web application, one instance of the bean is created for each request.

二、@Scope的三种用法

1.在自动扫描中

1 @Component
2 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
3 public class Notepad { ... }

2.在java配置文件中

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Notepad notepad() {
    return new Notepad();
}
ww

3.在xml配置文件中

<bean id="notepad" class="com.myapp.Notepad" scope="prototype" />

三、

若不指明proxyMode,当把一个session或request的bean注入到sigleton的bean时,会出现问题。如把购物车bean注入到service bean

1 @Component
2 @Scope(
3     value = WebApplicationContext.SCOPE_SESSION,
4     proxyMode = ScopedProxyMode.INTERFACES)
5 public ShoppingCart cart() {... }
@Component
public class StoreService {
    @Autowired
    public void setShoppingCart(ShoppingCart shoppingCart) {
            this.shoppingCart = shoppingCart;
        }
        ...
}

因为StoreService是signleton,是在容器启动就会创建,而shoppingcart是session,只有用户访问时才会创建,所以当StoreService企图要注入shoppingcart时,很有可能shoppingcart还没创建。spring用代理解决这个问题,当ShoppingCart是接口时,指定 ScopedProxyMode.INTERFACES。当ShoppingCart是一个类时,则指定ScopedProxy- Mode.TARGET_CLASS,srping会通过CGLib来创建基于类的代理对象。当request注入到signleton bean时,也是一样。

在xml中声明proxy策略

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <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="
 3 http://www.springframework.org/schema/aop
 4 http://www.springframework.org/schema/aop/spring-aop.xsd
 5 http://www.springframework.org/schema/beans
 6 http://www.springframework.org/schema/beans/spring-beans.xsd">
 7 
 8     <bean id="cart" class="com.myapp.ShoppingCart" scope="session">
 9         <aop:scoped-proxy />
10     </bean>
11 </beans>

<aop:scoped-proxy> is the Spring XML configuration’s counterpart to the @Scope
annotation’s proxyMode attribute. It tells Spring to create a scoped proxy for the bean.
By default, it uses CGL ib to create a target class proxy. But you can ask it to generate an
interface-based proxy by setting the proxy-target-class attribute to false :

<bean id="cart" class="com.myapp.ShoppingCart" scope="session">
    <aop:scoped-proxy proxy-target-class="false" />
</bean>
原文地址:https://www.cnblogs.com/shamgod/p/5236060.html