Spring@Autowired注解自动注入流程是怎么样?

面试中碰到面试官问:”Spring 注解是如果工作的?“,当前我一惊,完了这不触及到我的知识误区了吗?,还好我机智,灵机一动回了句:Spring 注解的工作流程倒还没有看到,但是我知道@Autowired注解的工作流程,后面不用说了一顿巴拉,面试官都连连点头。

面试中要活用转移话题,要避免回答 ”不知道“,要引导面试官掉入你擅长的技术,然后才有机会教他作人。

@Autowired 相关的类

@Autowired 注解的主要功能就是完成自动注入,使用也非常简单(Spring都安排好了),但是要想知道 @Autowired 注解的内部现实,就需要看一下Spring源码了。接下来一步步的解剖 @Autowired 的实现原理,首先理一下与 @Autowired 注解相关的类,然后一步步的跟踪源码,直到理解 @Autowired 的原理。

AutowiredAnnotationBeanPostProcessor 类

AutowiredAnnotationBeanPostProcessor是实现 @Autowired 功能的主要类,它有一些方法是会用解析 @Autowired 注解并实现自动注入的功能,下面是它的继承图:
在这里插入图片描述

Spring@Autowired注解自动注入流程是怎么样?
从上图可以发现 AutowiredAnnotationBeanPostProcessor 最上层是 BeanPostProcessor 是一个后处理器,当然除了后处理器外中间还有InstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor:

InstantiationAwareBeanPostProcessor 接口

postProcessBeforeInstantiation方法

在Bean实例化之前调用,可以返回一个Bean实例,默认返回null。

@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String 
beanName) throws BeansException {
         return null;}

postProcessAfterInstantiation方法

在Bean创建完成后,设置属性之前调用。

default boolean postProcessAfterInstantiation(Object bean, String 
beanName) throws BeansException {
         return true;}

postProcessProperties方法

@Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object 
bean, String beanName)            throws BeansException {
         return null;}

Bean创建完后,设置属性之前调用

先记住 InstantiationAwareBeanPostProcessor 接口,后面会跟踪调用它的地方,就很容易理解了。

MergedBeanDefinitionPostProcessor

MergedBeanDefinitionPostProcessor 也是一个继承 BeanPostProcessor 接口的后处理器,它的主要作用就是可以处理操作BeanDefinition对象,由于Bean的实例化是通过 BeanDefinition 的, 通过操作BeanDefinition ,这样可以使Bean的实例化时发生一些变化。

MergedBeanDefinitionPostProcessor 只有两个方法

postProcessMergedBeanDefinition方法

void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, 
Class<?> beanType, String beanName);

Bean的BeanDefinition 被合并后调用此方法。

resetBeanDefinition

default void resetBeanDefinition(String beanName) {
   }

当一个BeanDefinition被重置后调用 。

AutowireCapableBeanFactory 接口

AutowireCapableBeanFactory继承自BeanFactory,除了提供基础的Bean操作外,从接口的名字就可以推断出的它还有自动注入的能力。AutowireCapableBeanFactory 提供四种注入模型:

  • AUTOWIRE_NO: 没有显示的定义注入模型
  • AUTOWIRE_BY_NAME: 通过Bean名称注入
  • AUTOWIRE_BY_TYPE: 通过Bean的类型注入
  • AUTOWIRE_CONSTRUCTOR:通过Bean的构造方法注入

AutowireCapableBeanFactory 接口有不少方法,但大部分都是跟自动注入的相关。@Autowired 的主要功能就是在Bean实例化后,为其设置属性,所以在 AutowireCapableBeanFactory 接口有一个createBean方法,用于创建Bean并设置Bean的属性:

<T> T createBean(Class<T> beanClass) throws BeansException;

createBean方法,它的调用时机是创建Bean的时候,稍后会说到它的调用时机。

AbstractAutowireCapableBeanFactory

在这里插入图片描述

Spring@Autowired注解自动注入流程是怎么样?
AbstractAutowireCapableBeanFactory 继承 AbstractBeanFactory并实现了AutowireCapableBeanFactory接口,所以它也实现了AutowireCapableBeanFactory中的createBean方法。

public <T> T createBean(Class<T> beanClass) throws BeansException {
        

// Use prototype bean definition, to avoid registering bean as dependent bean.      

RootBeanDefinition bd = new RootBeanDefinition(beanClass);      
bd.setScope(SCOPE_PROTOTYPE);     

bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());      

return (T) createBean(beanClass.getName(), bd, null);}

Bean创建的生命周期

通过了解Bean创建的生命周期,才可以将上面与 @Autowired 相关的类串起来,首先这里不会过多的介绍Bean的创建细节,只关注自动注入相关的代码。

Bean的创建过程

Spring中默认的Bean都是懒加载的,所以一个Bean的创建会从调用getBean方法开始,如果不考虑缓存、上层容器的情况,Bean的创建会经过以下方法:

  • getBean:BeanFactory的方法,获取Bean实例
  • doGetBean:获取Bean的实例,获取顺序依次为:单例池、父容器,如果从以上2种途径都没获取到Bean实例就会创建新的
  • createBean:创建 Bean,这里的createBean,跟上面介绍的是一回事
  • doCreateBean:创建Bean实例
  • populateBean:设置Bean属性

以上流程中的getBean和doGetBean不多作说明了, 重点关注createBean前面提到AbstractAutowireCapableBeanFactory.createBean方法,所以说你在调用getBean方法获取Bean的实例时,如果这个Bean实例还没有被创建,那么createBean就会被调用。

通过简单的说明Bean创建的生命周期,就能找到 @Autowired 注解实现的入口,接下来再继续跟踪createBean方法。

收集注入元信息

收集注入元信息的步骤的,其实就是调用AutowiredAnnotationBeanPostProcessor类方法来实现的。

Bean 创建之前
以下是createBean方法,在Bean创建之前调用postProcessBeforeInstantiation的地方。为是阅读方便省略了一些代码,大致的流程就是:

  • 首先调用 resolveBeforeInstantiation 方法,执行
    InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法
  • 如果postProcessBeforeInstantiation返回Bean实例那么直接返回这
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值