Spring源码(十)-寻找注入点-MergedBeanDefinitionPostProcessor

1,294 阅读10分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

日积月累,水滴石穿 😄

前言

前面几篇已经分析完了 Bean 是如何被创建出来的,那本篇就来分析 Spring 是如何知道 Bean 中的哪些属性是需要被注入的!

该方法位于 AbstractAutowireCapableBeanFactory类。相信各位看到这段代码应该不会陌生了吧!执行 BeanPostProcessors 。如果不知道 BeanPostProcessors 有什么作用,如何使用,可以先去看看小杰的另外一篇文章:Spring源码-BeanPostProcessor

protected void applyMergedBeanDefinitionPostProcessors(
  RootBeanDefinition mbd, Class <? > beanType, String beanName) {  
  for(BeanPostProcessor bp: getBeanPostProcessors()) {    
    if(bp instanceof MergedBeanDefinitionPostProcessor) {      
      MergedBeanDefinitionPostProcessor bdp = (
        MergedBeanDefinitionPostProcessor) bp;      
      bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);   
    } 
  }
}

这里会执行所有实现了MergedBeanDefinitionPostProcessor接口的 BeanPostProcessorimage.png

可以看到实现了 MergedBeanDefinitionPostProcessor接口的类还是挺多的。分别有以下实现:

  • AutowiredAnnotationBeanPostProcessor:解析AutowiredValueInject注解。
  • ScheduledAnnotationBeanPostProcessor:解析 Scheduled注解。
  • InitDestroyAnnotationBeanPostProcessor:解析PreDestroyPostConstruct注解。
  • JmsListenerAnnotationBeanPostProcessor:解析JmsListener注解。
  • PersistenceAnnotationBeanPostProcessor:解析@PersistenceUnit@PersistenceContext注解。
  • CommonAnnotationBeanPostProcessor:解析@Resource@WebServiceRef@EJB注解。并且该类继承了 InitDestroyAnnotationBeanPostProcessor

本篇将介绍 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor这两个BeanPostProcessor

AutowiredAnnotationBeanPostProcessor

在所有的实现类中,选择AutowiredAnnotationBeanPostProcessor类。先来看看AutowiredAnnotationBeanPostProcessor 类的继承图。 image-20210904104055165.png

既然要解析这AutowiredValueInject三个注解,那么在AutowiredAnnotationBeanPostProcessor类中肯定要有这三个注解的相关代码。

public AutowiredAnnotationBeanPostProcessor() {
  this.autowiredAnnotationTypes.add(Autowired.class);
  this.autowiredAnnotationTypes.add(Value.class);
  try {
    this.autowiredAnnotationTypes.add((Class <? extends Annotation > ) ClassUtils
      .forName("javax.inject.Inject",
        AutowiredAnnotationBeanPostProcessor.class.getClassLoader()
      ));
    logger.trace(
      "JSR-330 'javax.inject.Inject' annotation found and supported for autowiring"
    );
  }
  catch(ClassNotFoundException ex) {
    // JSR-330 API not available - simply skip.
  }
}

可以看到这是一个无参构造方法,往 autowiredAnnotationTypes属性中添加值。后面逻辑肯定会用到这个属性,判断当前类中是否包含 autowiredAnnotationTypes属性的值。


好的,下面进入到正题,看看是如何去寻找注入点的。

方法传入三个入参,分别如下:

  • beanDefinition:当前 bean 的定义
  • beanType:实例对象的类型
  • beanName:bean 名称
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
  Class <? > beanType, String beanName) {
  // 获取beanType中的注入点
  InjectionMetadata metadata = findAutowiringMetadata(beanName,
    beanType, null);
  metadata.checkConfigMembers(beanDefinition);
}

重点看一下 findAutowiringMetadata方法。

private InjectionMetadata findAutowiringMetadata(String beanName,
  Class <? > clazz, @Nullable PropertyValues pvs) {
  // 如果当前 beanName 为null,那就选择class对象的名称
  String cacheKey = (StringUtils.hasLength(beanName) ? beanName :
    clazz.getName());
  // 从缓存中获取
  InjectionMetadata metadata = this.injectionMetadataCache.get(
    cacheKey);
  //如果缓存中有,不需要再次解析
  //needsRefresh = true 需要解析
  if(InjectionMetadata.needsRefresh(metadata, clazz)) {
    synchronized(this.injectionMetadataCache) {
      metadata = this.injectionMetadataCache.get(cacheKey);
      if(InjectionMetadata.needsRefresh(metadata, clazz)) {
        if(metadata != null) {
          metadata.clear(pvs);
        }
        // 寻找当前clazz中的注入点,把所有注入点整合成为一个InjectionMetadata对象
        metadata = buildAutowiringMetadata(clazz);
        // 添加到缓存中
        this.injectionMetadataCache.put(cacheKey, metadata);
      }
    }
  }
  return metadata;
}

调试进入 buildAutowiringMetadata 方法:

private InjectionMetadata buildAutowiringMetadata(final Class <? >
  clazz) {
  // 判断是不是候选者类,
  //1、先判断注解的全限名称是否以"java."开头,如果是则返回true,否则进行第二步(如果类名的全路径是 java.xx.xx,启动的时候就会报错的)
  //2、判断类的名称是否以"java."开头 或者 clazz的类型为 org.springframework.core.Ordered.class,如果是返回 false
  if(!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
    return InjectionMetadata.EMPTY;
  }
  List <InjectionMetadata.InjectedElement> elements = new ArrayList<> ();
  Class <?> targetClass = clazz;
  do {
    final List <InjectionMetadata.InjectedElement> currElements =
      new ArrayList <> ();
    // 遍历属性,看是否有@Autowired,@Value,@Inject注解
    ReflectionUtils.doWithLocalFields(targetClass, field - > {
      //
      MergedAnnotation <?> ann = findAutowiredAnnotation(field); >1
      // 如果存在@Autowired,@Value,@Inject注解其中一个
      if(ann != null) {
        // 如果字段是static的,则直接进行返回,不进行注入
        if(Modifier.isStatic(field.getModifiers())) {
          if(logger.isInfoEnabled()) {
            logger.info(
              "Autowired annotation is not supported on static fields: " +
              field);
          }
          return;
        }
        // 是否required
        boolean required = determineRequiredStatus(ann);
        // 生成一个注入点AutowiredFieldElement
        currElements.add(new AutowiredFieldElement(field,
          required));
      }
    });
    // 遍历方法,看是否有@Autowired,@Value,@Inject注解
    ReflectionUtils.doWithLocalMethods(targetClass, method - > {
      Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(
        method);
      if(!BridgeMethodResolver.isVisibilityBridgeMethodPair(
          method, bridgedMethod)) {
        return;
      }
      MergedAnnotation <?> ann = findAutowiredAnnotation(
        bridgedMethod);
      if(ann != null && method.equals(ClassUtils.getMostSpecificMethod(
          method, clazz))) {
        // 静态方法不能用来注入属性
        if(Modifier.isStatic(method.getModifiers())) {
          if(logger.isInfoEnabled()) {
            logger.info(
              "Autowired annotation is not supported on static methods: " +
              method);
          }
          return;
        }
        // 方法参数个数为0,打印日志提示
        if(method.getParameterCount() == 0) {
          if(logger.isInfoEnabled()) {
            logger.info(
              "Autowired annotation should only be used on methods with parameters: " +
              method);
          }
        }
        boolean required = determineRequiredStatus(ann);
        // 根据方法找出对应的属性描述 可能为 null(PropertyDescriptor下篇会将到)
        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(
          bridgedMethod, clazz);
        currElements.add(new AutowiredMethodElement(method,
          required, pd));
      }
    });
    // 所有能够注入的属性集合
    elements.addAll(0, currElements);
    // 获得当前类的父类(当前类可能是一个代理类)
    targetClass = targetClass.getSuperclass();
  }
  // 当前类不等于 null 并且当前类不是Object 则继续遍历
  while (targetClass != null && targetClass != Object.class);
  // 构建 InjectionMetadata 对象
  return InjectionMetadata.forElements(elements, clazz);
}

看一下标记点>1 findAutowiredAnnotation方法。

@Nullable
private MergedAnnotation <? > findAutowiredAnnotation(
  AccessibleObject ao) {
  // 查找当前字段或者方法上是否存在@Autowired,@Value,@Inject注解,并将之方法,可能会返回多个
  //因为可以这么写:
  //@Autowired
  //@Value("sss")
  //private BB b;
  MergedAnnotations annotations = MergedAnnotations.from(ao);
  // autowiredAnnotationTypes是一个LinkedHashSet,所以会按顺序去判断当前字段中是否有Autowired注解,如果有则返回
  // 如果没有Autowired注解,那么则判断是否有Value注解,再判断是否有Inject注解
  for(Class<? extends Annotation> type: this.autowiredAnnotationTypes) {
    MergedAnnotation <?> annotation = annotations.get(type);
    if(annotation.isPresent()) {
      return annotation;
    }
  }
  return null;
}

方法中的逻辑还是挺简单的。

  • 1、根据传入的 Class 类型,先去判断是不是候选者类,如果类名是以"java."开头或者Class的类型为 org.springframework.core.Ordered.class就不是候选者类。
  • 2、开启 do、while 循环。
  • 3、获得当前类的所有属性(包括public、private和proteced),遍历每个属性上是否包含 @Autowired,@Value,@Inject注解,如果属性上存在注解,则判断当前属性是否是static的,如果字段是static的,则直接进行返回,不进行记录,代表当前属性不能进行注入。如果不是static的,生成一个注入点AutowiredFieldElement添加到 currElements中。
  • 4、获得当前类的所有方法(包括private、protected、public),遍历每个方法上是否包含 @Autowired,@Value,@Inject注解,如果方法上存在注解,则判断当前方法是否是static的,如果方法是static的,则直接进行返回,不进行记录。如果当前方法不是static的,根据方法找出对应的属性,生成一个注入点AutowiredMethodElement添加到 currElements中。

实例

测试 isCandidateClass方,判断是不是候选者类。

  • CC注解
package java;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({
  ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
    ElementType.ANNOTATION_TYPE
})
@Retention(RetentionPolicy.RUNTIME)
public@ interface CC {}
  • 启动类
public static void main(String[] args) {
   Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
  // autowiredAnnotationTypes.add(Autowired.class);
 //  autowiredAnnotationTypes.add(Value.class);
   autowiredAnnotationTypes.add(CC.class);
   boolean candidateClass = AnnotationUtils.isCandidateClass(CC.class, autowiredAnnotationTypes);
   System.out.println("结果 = " + candidateClass);
}

结果 = true

CommonAnnotationBeanPostProcessor

image-20210905214414746.png

AutowiredAnnotationBeanPostProcessor的注入点解析已经完成了,小杰带各位小伙伴再来看看CommonAnnotationBeanPostProcessor的注入点解析。还是老套路,既然要解析这WebServiceRefEJBResource三个注解,那么在CommonAnnotationBeanPostProcessor类中肯定要有这三个注解的相关代码。

static {
  try {
    @SuppressWarnings("unchecked")
    Class<? extends Annotation> clazz = (Class<? extends Annotation>)
    ClassUtils.forName("javax.xml.ws.WebServiceRef",
      CommonAnnotationBeanPostProcessor.class.getClassLoader());
    webServiceRefClass = clazz;
  }
  catch(ClassNotFoundException ex) {
    webServiceRefClass = null;
  }
  try {
    @SuppressWarnings("unchecked")
    Class <? extends Annotation> clazz = (Class <? extends Annotation>)
    ClassUtils.forName("javax.ejb.EJB",
      CommonAnnotationBeanPostProcessor.class.getClassLoader());
    ejbRefClass = clazz;
  }
  catch(ClassNotFoundException ex) {
    ejbRefClass = null;
  }
  resourceAnnotationTypes.add(Resource.class);
  if(webServiceRefClass != null) {
    resourceAnnotationTypes.add(webServiceRefClass);
  }
  if(ejbRefClass != null) {
    resourceAnnotationTypes.add(ejbRefClass);
  }
}

这次不是在无参构造方法中进行初始化了,是放在静态代码块中,向resourceAnnotationTypes属性中添加值。

那再来看看无参构造方法。

public CommonAnnotationBeanPostProcessor() {
    setOrder(Ordered.LOWEST_PRECEDENCE - 3);
    setInitAnnotationType(PostConstruct.class);
    setDestroyAnnotationType(PreDestroy.class);
    ignoreResourceType("javax.xml.ws.WebServiceContext");
}

前面三个方法是调用父类InitDestroyAnnotationBeanPostProcessor中的方法,进行属性赋值。

public void setOrder(int order) {
    this.order = order;
}

public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
    this.initAnnotationType = initAnnotationType;
}

public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
    this.destroyAnnotationType = destroyAnnotationType;
}

最后一个方法是给本类属性赋值。

//忽略的资源类型
private final Set<String> ignoredResourceTypes = new HashSet<>(1);

public void ignoreResourceType(String resourceType) {
    Assert.notNull(resourceType, "Ignored resource type must not be null");
    this.ignoredResourceTypes.add(resourceType);
}

OK,了解了一下前置知识,进入到主流程中。

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
  Class <? > beanType, String beanName) {
    //调用父类 InitDestroyAnnotationBeanPostProcessor
  super.postProcessMergedBeanDefinition(beanDefinition, beanType,
    beanName);
    
  InjectionMetadata metadata = findResourceMetadata(beanName,
    beanType, null);
  metadata.checkConfigMembers(beanDefinition);
}

首先会调用父类的postProcessMergedBeanDefinition方法,然后调用本类findResourceMetadata方法。

上面我们讲到CommonAnnoatationBeanPostProcessor的父类是InitDestoryAnnoatationBeanPostProcessor,在InitDestoryAnnoatationBeanPostProcessor类中postProcessMergedBeanDefinition方法会解析和初始化(@PostConstruct)和销毁(@PreDestory)注解并缓存到lifecycleMetadataCache中。

父类

那我先来看一下 InitDestoryAnnoatationBeanPostProcessor类中的 postProcessMergedBeanDefinition方法。

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
  Class <?> beanType, String beanName) {
  LifecycleMetadata metadata = findLifecycleMetadata(beanType);
  metadata.checkConfigMembers(beanDefinition);
}

然后再进入findLifecycleMetadata方法,传入实例对象的类型。

private LifecycleMetadata findLifecycleMetadata(Class <?> clazz) {
  //lifecycleMetadataCache属性是一个 Map clazz 为key  LifecycleMetadata 为值 
  if(this.lifecycleMetadataCache == null) {
    // Happens after deserialization, during destruction...
    return buildLifecycleMetadata(clazz);
  }
  // Quick check on the concurrent map first, with minimal locking.
  LifecycleMetadata metadata = this.lifecycleMetadataCache.get(
    clazz);
  if(metadata == null) {
    synchronized(this.lifecycleMetadataCache) {
      metadata = this.lifecycleMetadataCache.get(clazz);
      if(metadata == null) {
        metadata = buildLifecycleMetadata(clazz);
        //将结果缓存在lifecycleMetadataCache中
        this.lifecycleMetadataCache.put(clazz, metadata);
      }
      return metadata;
    }
  }
  return metadata;
}

关注buildLifecycleMetadata方法,其他逻辑就是判断缓存里面有没有。

private LifecycleMetadata buildLifecycleMetadata(final Class <? >
  clazz) {
  //判断是不是候选者,逻辑与一致,不在哔哔了
  // initAnnotationType 存的是 PostConstruct
  // destroyAnnotationType 存的是 PreDestroy
  if(!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType,
      this.destroyAnnotationType))) {
    return this.emptyLifecycleMetadata;
  }
  List <LifecycleElement> initMethods = new ArrayList <> ();
  List <LifecycleElement> destroyMethods = new ArrayList <> ();
  Class <?> targetClass = clazz;
  do {
    final List <LifecycleElement> currInitMethods = new ArrayList<>();
    final List <LifecycleElement> currDestroyMethods = new ArrayList<>();
    //遍历当前类方法,看是否有@PostConstruct,@PreDestroy注解
    ReflectionUtils.doWithLocalMethods(targetClass, method - > {
      //当前方法上包含 @PostConstruct 注解
      if(this.initAnnotationType != null && method.isAnnotationPresent(
          this.initAnnotationType)) {
        //构建LifecycleElement对象
        LifecycleElement element = new LifecycleElement(method);
        //将 LifecycleElement 对象添加到集合中
        currInitMethods.add(element);
        if(logger.isTraceEnabled()) {
          logger.trace("Found init method on class [" + clazz.getName() +
            "]: " + method);
        }
      }
      //当前方法上包含 @PreDestroy 注解
      if(this.destroyAnnotationType != null && method.isAnnotationPresent(
          this.destroyAnnotationType)) {
        currDestroyMethods.add(new LifecycleElement(method));
        if(logger.isTraceEnabled()) {
          logger.trace("Found destroy method on class [" +
            clazz.getName() + "]: " + method);
        }
      }
    });
    initMethods.addAll(0, currInitMethods);
    destroyMethods.addAll(currDestroyMethods);
    targetClass = targetClass.getSuperclass();
  }
  while (targetClass != null && targetClass != Object.class);
  return(initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
    new LifecycleMetadata(clazz, initMethods, destroyMethods));
}

相比较于AutowiredAnnotationBeanPostProcessor中的逻辑简单了许多,遍历所有的方法,判断每个方法上是否标注了 @PostConstruct@PreDestroy注解(可以得出这两个注解只能写在方法上),分别存入initMethodsdestroyMethods两个集合中,并将结果缓存在lifecycleMetadataCache中。

本类

看看本类的findResourceMetadata方法。

private InjectionMetadata findResourceMetadata(String beanName, 
final Class <?> clazz, @Nullable PropertyValues pvs) {
 // 如果当前 beanName 为null,那就选择class对象的名称
  String cacheKey = (StringUtils.hasLength(beanName) ? beanName :
    clazz.getName());
    // 从缓存中获取
  InjectionMetadata metadata = this.injectionMetadataCache.get(
    cacheKey);
  if(InjectionMetadata.needsRefresh(metadata, clazz)) {
    synchronized(this.injectionMetadataCache) {
      metadata = this.injectionMetadataCache.get(cacheKey);
      if(InjectionMetadata.needsRefresh(metadata, clazz)) {
        if(metadata != null) {
          metadata.clear(pvs);
        }
        metadata = buildResourceMetadata(clazz);
        //将结果缓存起来
        //injectionMetadataCache 是一个Map
        //key 为 beanName
        //value 为 InjectionMetadata 对象
        this.injectionMetadataCache.put(cacheKey, metadata);
      }
    }
  }
  return metadata;
}

额!关注buildResourceMetadata方法。

private InjectionMetadata buildResourceMetadata(final Class <?>
  clazz) {
  //不哔哔
  if(!AnnotationUtils.isCandidateClass(clazz,
      resourceAnnotationTypes)) {
    return InjectionMetadata.EMPTY;
  }
  List <InjectionMetadata.InjectedElement> elements = new ArrayList<>();
  Class <?> targetClass = clazz;
  do {
    final List <InjectionMetadata.InjectedElement> currElements =
      new ArrayList <> ();
    //遍历所有字段属性,看是否有@WebServiceRef,@EJB,@Resource注解
    ReflectionUtils.doWithLocalFields(targetClass, field - > {
      //当前属性上包含 @WebServiceRef 注解
      if(webServiceRefClass != null && field.isAnnotationPresent(
          webServiceRefClass)) {
        //是否是静态属性 如果是抛出异常
        if(Modifier.isStatic(field.getModifiers())) {
          throw new IllegalStateException(
            "@WebServiceRef annotation is not supported on static fields"
          );
        }
        //构建一个 WebServiceRefElement 对象添加到集合中
        currElements.add(new WebServiceRefElement(field, field,
          null));
      }
      //当前属性上包含 @EJB 注解
      else if(ejbRefClass != null && field.isAnnotationPresent(
          ejbRefClass)) {
        //是否是静态属性 如果是抛出异常
        if(Modifier.isStatic(field.getModifiers())) {
          throw new IllegalStateException(
            "@EJB annotation is not supported on static fields"
          );
        }
        //构建一个 EjbRefElement 对象添加到集合中
        currElements.add(new EjbRefElement(field, field, null));
      }
      //当前属性上包含 @Resource 注解
      else if(field.isAnnotationPresent(Resource.class)) {
        //是否是静态属性 如果是抛出异常
        if(Modifier.isStatic(field.getModifiers())) {
          throw new IllegalStateException(
            "@Resource annotation is not supported on static fields"
          );
        }
        //当前属性类型的名称不能包含 javax.xml.ws.WebServiceContext
        //也就是说你不能使用以下写法:
        //@Resource
        //private WebServiceContext wsContext;
        if(!this.ignoredResourceTypes.contains(field.getType().getName())) {
          //构建一个 ResourceElement 对象添加到集合中
          currElements.add(new ResourceElement(field, field,
            null));
        }
      }
    });
    //遍历当前类所有方法,看是否有@WebServiceRef,@EJB,@Resource注解
    ReflectionUtils.doWithLocalMethods(targetClass, method - > {
      Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(
        method);
      if(!BridgeMethodResolver.isVisibilityBridgeMethodPair(
          method, bridgedMethod)) {
        return;
      }
      if(method.equals(ClassUtils.getMostSpecificMethod(method,
          clazz))) {
        //当前方法上包含 @WebServiceRef 注解
        if(webServiceRefClass != null && bridgedMethod.isAnnotationPresent(
            webServiceRefClass)) {
          // 如果静态方法则抛出异常
          if(Modifier.isStatic(method.getModifiers())) {
            throw new IllegalStateException(
              "@WebServiceRef annotation is not supported on static methods"
            );
          }
          // 方法参数个数只能是一个,否则抛出异常
          if(method.getParameterCount() != 1) {
            throw new IllegalStateException(
              "@WebServiceRef annotation requires a single-arg method: " +
              method);
          }
          PropertyDescriptor pd = BeanUtils.findPropertyForMethod(
            bridgedMethod, clazz);
          //构建 WebServiceRefElement 对象 添加到 currElements 集合中
          currElements.add(new WebServiceRefElement(method,
            bridgedMethod, pd));
        }
        //当前方法上包含 @EJB 注解
        else if(ejbRefClass != null && bridgedMethod.isAnnotationPresent(
            ejbRefClass)) {
          // 如果静态方法则抛出异常
          if(Modifier.isStatic(method.getModifiers())) {
            throw new IllegalStateException(
              "@EJB annotation is not supported on static methods"
            );
          }
          // 方法参数个数只能是一个,否则抛出异常
          if(method.getParameterCount() != 1) {
            throw new IllegalStateException(
              "@EJB annotation requires a single-arg method: " +
              method);
          }
          PropertyDescriptor pd = BeanUtils.findPropertyForMethod(
            bridgedMethod, clazz);
          //构建 EjbRefElement 对象 添加到 currElements 集合中
          currElements.add(new EjbRefElement(method,
            bridgedMethod, pd));
        }
        //当前方法上包含 @Resource 注解
        else if(bridgedMethod.isAnnotationPresent(Resource.class)) {
          if(Modifier.isStatic(method.getModifiers())) {
            // 如果静态方法则抛出异常
            throw new IllegalStateException(
              "@Resource annotation is not supported on static methods"
            );
          }
          //获得参数的类型
          Class <?> [] paramTypes = method.getParameterTypes();
          // 参数类型长度只能是 1,也就是方法参数个数只能是一个,否则抛出异常
          if(paramTypes.length != 1) {
            throw new IllegalStateException(
              "@Resource annotation requires a single-arg method: " +
              method);
          }
          //当前方法参数类型的名称不能包含 javax.xml.ws.WebServiceContext
          if(!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
            PropertyDescriptor pd = BeanUtils.findPropertyForMethod(
              bridgedMethod, clazz);
            //构建 ResourceElement 对象 添加到 currElements 集合中
            currElements.add(new ResourceElement(method,
              bridgedMethod, pd));
          }
        }
      }
    });
    elements.addAll(0, currElements);
    targetClass = targetClass.getSuperclass();
  }
  while (targetClass != null && targetClass != Object.class);
  return InjectionMetadata.forElements(elements, clazz);
}

大体逻辑都差不多的,就是解析属性或者方法上有没有注解,属性、方法是不是静态的。

总结

到此呢,AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor的注入点分析都已经完成啦~。都会将值缓存起来,AutowiredAnnotationBeanPostProcessor将值缓存在AutowiredAnnotationBeanPostProcessor的属性injectionMetadataCache中,CommonAnnotationBeanPostProcessor将值缓存在CommonAnnotationBeanPostProcessor类的属性injectionMetadataCache中。InitDestoryAnnoatationBeanPostProcessor将值缓存在InitDestoryAnnoatationBeanPostProcessor类中的属性lifecycleMetadataCache中。

之后的博文会分析如何使用AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 缓存中的信息,这两者的信息是在postProcessPerties方法中被使用。

至于InitDestoryAnnoatationBeanPostProcessor的缓存信息,PostConstruct是在 postProcessBeforeInitialization初始化前方法中被执行,PreDestroy是在postProcessBeforeDestruction销毁前方法中被执行。