代码 https://gitee.com/fysola/Spring-Learning/tree/master/Spring_LookUp
Spring Bean的Scope
spring中主要分 singleton和prototype的bean(其他四种都是web用暂时不说) 默认情况下是singleton的,只有显式注明prototype才是prototype类型的bean
一个context中对于singleton的bean只会有一个实例,其生命周期由spring context管理 通常一个不需要维护状态的bean,例如service, controller, dao等bean,都可以定义为singleton的bean 而prototype则会在每次注入别的bean,或者调用context.getBean()时返回新的实例,因此这种 bean时候需要维护独立状态的bean,例如购物车bean
singleton中注入prototype ben的问题
spring实例化一个bean时会先实例话它依赖的bean,对于singleton,spring只会实例化一次, 但是在有些场景下,例如购物场景: 购物服务属于公共无状态服务,一般定义成一个singleton的bean,购物车则通常定义为prototype 而通常又会在购物服务中注入购物车实例,以便向购物车添加商品, 如果使用传统的 @Autoware方式注入购物车实例,那么多个访客可能就共用了同一个购物车实例,因为 购物服务是单例的,注入只会发生一次。 为了解决这个问题,
spring提供了两个方案:
单例继承ApplicationContextAware
继承了ApplicationContextAware的购物服务bean可以拿到当前的context,从而调用context.getBean()获取 一个新的购物车bean,解决了脏数据问题。 但是这种方式不够灵活,毕竟要实现一个接口,显式地耦合了spring框架
使用@Lookup让spring生成代理服务类
spring会使用CGLIB库的动态代理生成服务类的子类重写@Lookup的方法,变相实现了context.getBean()