Spring单例对象中引用非单例对象的方式:购物车问题的解决方案

本文探讨了如何在Spring框架中处理单例对象引用非单例对象的问题,以购物车为例。通过创建会话生命周期的ShoppingCart bean,并利用Spring的代理机制,确保StoreService在处理购物车时使用的是当前会话对应的实例。Spring提供了基于JDK动态代理或CGlib的代理方式来实现这一目标,通过<aop:scoped-proxy>配置进行声明。这种解决方案有助于解决不同生命周期bean之间的耦合问题,鼓励开发者深入思考每个细节,优化代码稳定性。
摘要由CSDN通过智能技术生成

我相信我们每个人都有网上购物的经历,当我们进入购物网站的时候,比如京东,我们的账户里面就会有一个购物车,但是这个购物车是哪来的呢,或者我们在其他地方再次登陆的时候,是不是同一个购物车呢? 答案是肯定的,那他是怎么做到的呢,有机智的小伙伴可能会说,可以创建一个session,或者cookie,只要是同一个会话,他们就是同一个购物车,说的很对,我们可以创建一个会话生命周期的购物车,但我们知道,整个网站是一直在运行的,我们可以理解他为单例生命周期,而购物车我们可以理解为会话生命周期,对于单例和会话两个不同的生命周期的bean,我们应该怎样耦合呢,下面我们给出我们的答案。


@Component
public classs StoreService{
     @Autowired
     public void setShoppingCart(ShoppingCart shoppingCart){
           this.shoppingCart = shoppingCart;

     }

}

我们把一个网站服务定义为@Bean StoreService 他是单例的,会在Spring应用上下文加载的时候被创建,当他创建的时候Spring会试图将ShoppingCart bean注入到setShoppingCart()方法中,但是ShoppingCart bean是会话作用域此时并不存在,直到某个用户登陆了系统创建会话之后才会出现ShoppingCart实例。

另外,系统中将不止这一个ShoppingCart实例:每个用户一个。我们并不希望让Spring注入某个固定的ShoppingCart实例到StoreService中。我们希望的是当StoreService处理购物车功能时,它所使用的ShoppingCart实例恰好是当前会话所对应的那一个。

        Spring并不会将实际的ShoppingCart bean注入到StoreService中,Spring会注入一个到ShoppingCart bean的代理,这个代理会暴露与ShoppingCart相同的方法,所以StoreService会认为他就是一个购物车,但是,当StoreService调用ShoppingCart的方法时,代理会调用真正注入到当前会话的ShoppingCart。




如图所示,Spring在处理单例生命周期和个会话生命周期时,可以采用如图所示基于代理的方式,代理是整个应用中一直存在的,所以他可以跟我们的单例@Bean StoreService 进行交流, 同时代理又暴露了与会话生命周期@Bean ShoppingCart 连接点,基于Spring的动态代理模式。.

生成代理的方式有两种 如果ShoppingCart 是接口的话,可以使用基于JDK的动态代理,如果是类的话,可以用CGlib代理,但这些Spring早就帮我们实现好了,我们只需要在我们的Spring.xml中声明<aop:scoped-proxy ??>配置即可。

这是一种解决单例与非单例生命周期矛盾的一种方法,如果大家有什么好的思路,可以在下面发表评论一起交流,千里之行,始于足下, 思考每一个细节,让自己的代码变得简单而又稳定,这将对你的应用产生意想不到的优化。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值