原文地址:https://www.cnblogs.com/shamgod/p/5236060.html
一、
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.在自動掃描中
@Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class Notepad { ... }
2.在java配置文件中
@Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public Notepad notepad() { return new Notepad(); }
3.在xml配置文件中
<bean id="notepad" class="com.myapp.Notepad" scope="prototype" />
三、
若不指明proxyMode,當把一個session或request的bean注入到sigleton的bean時,會出現問題。如把購物車bean注入到service bean
@Component
@Scope(
value = WebApplicationContext.SCOPE_SESSION,
proxyMode = ScopedProxyMode.INTERFACES)
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策略
<?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/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="cart" class="com.myapp.ShoppingCart" scope="session"> <aop:scoped-proxy /> </bean> </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>