Spring之@Lookup注解

@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并返回。
在这里插入图片描述

总结

  1. 在bean实例化的过程中,执行推断构造方法时,会找到类方法上的@Lookup信息,并存到合并后的RootBeanDefinitionmethodOverrides属性中。
  2. 推断构造方法得到具体的构造方法后,进入真正的实例化流程,根据获取的实例化策略CglibSubclassingInstantiationStrategy,实例化时,先执行它父类SimpleInstantiationStrategy.instantiate()方法
  3. 判断methodOverrides有值的情况下,调用CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection()方法,生成Cglib代理对象调用instantiate()方法,生成LookupOverrideMethodInterceptor
  4. 执行LookupOverrideMethodInterceptor.intercept(),从beanDefinition拿到methodOverrides集合属性,拿到beanName从beanFactory即spring容器获取bean并返回。
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值