Spring实战读书笔记 高级装配(2)

一 、bean的作用域

单例(singleton):整个应用中,只创建一个bean的实例 (默认)
原型(prototype):每次注入或者通过spring上下文获取的时候,都会创建一个新的bean实例。
会话(session):在Web应用中,为每次会话创建一个新的bean实例。
请求(request):在Web应用中,为每次请求创建要给新的bean实例。

默认是singleton,如果需要使用其他作用域,可以使用 @scope注解:

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) //推荐 安全不易出错
//@Scope("prototype")
public class Notepad {
}

也可以使用xml配置

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

会话和请求作用域

例如,在电子商务应用中,有一个代表购物车的bean,如果是单例的话,那么将会导致所有的用户都会向一个购物车里添加商品。如果是原型的话,那么在应用中一个地方添加商品,在另一个地方就不能用了。
会话作用域是最合适的。

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION,
  proxyMode = ScopedProxyMode.INTERFACES)
public interface ShopingCart {
}

SCOPE_SESSION会告诉spring我为Web每个会话创建一个bean。在当前会话中这个bean其实是单例的。

proxyMode属性

@Component
public class StoreService {
    
    private  ShopingCart shopingCart;
    
    @Autowired
    public void setShopingCart(ShopingCart shopingCart) {
        this.shopingCart = shopingCart;
    }
}

StoreService是一个单例bean,会在spring上下文加载的时候创建。而shopingCart 是会话作用域。在StoreService加载的时候,shopingCart还不存在。只有某个用户进入系统才会出现。
而且,当系统中有多个shopingCart实例的时候,我们只希望自己会话中的shopingCart实例注入到StoreService中。

怎么解决的呢?
spring不会将实际的shopingCart注入进去,而是会注入一个shopingCart bean代理。这个代理暴露域shopingCart相同的方法。当进行方法调用时,代理会进行懒解析,并将调用委托给会话作用域中真正的shopingCart bean。
那么proxyMode属性
ScopedProxyMode.INTERFACES表明代理要通过接口实现。ScopedProxyMode.TARGET_CLASS基于类的代理。
在xml中声明作用域

   <bean id="cart" class="com.beanConfig.beanScope.ShopingCart" scope="session">
        <aop:scoped-proxy proxy-target-class="false"/>
    </bean>

默认时CGLib创建目标类代理。proxy-target-class=“false” 基于接口创建代理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值