@Autowired 的实现原理?

实现@Autowired的关键是:AutowiredAnnotationBeanPostProcessor

在Bean的初始化阶段,会经过一系列的前置和后置处理,其中使用后置处理器来完成@Autowired的功能。这个后置处理器就是AutowiredAnnotationBeanPostProcessor。

具体的实现过程如下:

  1. 在创建Bean的过程中,最终会调用doCreateBean()方法。在这个方法中,会调用populateBean()方法,用于进行属性填充和自动装配的工作。
  2. 在populateBean()方法中,会进行两次后置处理器的调用。第一次是用于判断是否需要进行属性填充,如果不需要填充属性,就直接返回;如果需要填充属性,就继续执行后续的操作。
  3. 第二次后置处理器的调用发生在postProcessPropertyValues()方法中,这个方法会解析@Autowired注解并实现自动装配的功能。
/**
* 属性赋值
**/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
          //…………
          if (hasInstAwareBpps) {
              if (pvs == null) {
                  pvs = mbd.getPropertyValues();
              }

              PropertyValues pvsToUse;
              for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
                  InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
                  pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                  if (pvsToUse == null) {
                      if (filteredPds == null) {
                          filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                      }
                      //执行后处理器,填充属性,完成自动装配
                      //调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法
                      pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                      if (pvsToUse == null) {
                          return;
                      }
                  }
              }
          }
         //…………
  }
  • postProcessorPropertyValues()方法的源码如下,在该方法中,会先调用 findAutowiringMetadata()方法解析出 bean 中带有@Autowired 注解、@Inject 和@Value 注解的属性和方法。然后调用 metadata.inject()方法,进行属性填充。
  public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
      //@Autowired注解、@Inject和@Value注解的属性和方法
      InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

      try {
          //属性填充
          metadata.inject(bean, beanName, pvs);
          return pvs;
      } catch (BeanCreationException var6) {
          throw var6;
      } catch (Throwable var7) {
          throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
      }
  }

标签: java, Java面试题, Java问题合集, Java编程, Java问题精选, Java常见问题