@Lookup应用场景
在一个单例bean UserService中,注入一个原型bean属性 OrderService,每次调用UserService时,拿到的OrderService是同一个,不符合原型的特性(每次获取都是新创建的bean)
UserService的作用域是单例,即每次都是从单例池中获取,获取不到则创建后放入单例池,每次都是获取的同一个

OrderService的作用域是原型,即每次获取都是新创建bean。

以上代码运行结果是每次调用userService.test()获取到的orderService是同一个,不符合原型特征。

使用@Lookup注解寻找beanName=orderService的bean,每次获取都是新的。


Lookup源码流程
在bean的生命周期“实例化”步骤中,会推断出合适的构造方法,在类AutowiredAnnotationBeanPostProcessor中会处理@Autowired以及@Lookup注解。
AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors()遍历类中的方法,找到加了@Lookup注解的方法,放到LookupOverride对象中,存入到合并后的RootBeanDefinition对象中methodOverrides集合属性中

存入到RootBeanDefinition对象的methodOverrides集合属性后,在bean的实例化流程AbstractAutowireCapableBeanFactory.doCreateBean()#createBeanInstance()中,会调用instantiateBean()方法来实例化生成bean。


实例化策略方法getInstantiationStrategy()默认返回CglibSubclassingInstantiationStrategy

在spring容器启动时,设置了默认的实例化策略是CglibSubclassingInstantiationStrategy

CglibSubclassingInstantiationStrategy的父类是SimpleInstantiationStrategy

先执行父类SimpleInstantiationStrategy.instantiate()方法

如果判断methodOverrides属性有值,会调用子类CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection()方法,最终生成了cglib代理对象。

执行cglib代理对象的instantiate()方法

生成LookupOverrideMethodInterceptor对象,并执行intercept()方法,从beanDefinition拿到methodOverrides集合属性,根据beanName直接从beanFactory即spring容器获取bean返回了,没有执行method.invoke(),意味着userService.xxx()方法不会执行,而是根据它方法上的@Lookup的值找到bean并返回。

总结
- 在bean实例化的过程中,执行推断构造方法时,会找到类方法上的
@Lookup信息,并存到合并后的RootBeanDefinition的methodOverrides属性中。 - 推断构造方法得到具体的构造方法后,进入真正的实例化流程,根据获取的实例化策略
CglibSubclassingInstantiationStrategy,实例化时,先执行它父类SimpleInstantiationStrategy.instantiate()方法 - 判断methodOverrides有值的情况下,调用
CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection()方法,生成Cglib代理对象调用instantiate()方法,生成LookupOverrideMethodInterceptor - 执行
LookupOverrideMethodInterceptor.intercept(),从beanDefinition拿到methodOverrides集合属性,拿到beanName从beanFactory即spring容器获取bean并返回。
Spring中Lookup注解的应用与实例化过程解析
本文详细解释了在Spring框架中,如何使用@Lookup注解实现单例bean与原型bean的区分,以及Lookup注解在bean实例化过程中的作用,着重剖析了CglibSubclassingInstantiationStrategy的实例化策略。
149

被折叠的 条评论
为什么被折叠?



