美文网首页Javaspring一些收藏
【Spring源码】10.IOC之@Autowired,@Val

【Spring源码】10.IOC之@Autowired,@Val

作者: 天还下着毛毛雨 | 来源:发表于2022-01-25 18:47 被阅读0次
image

前言

上一篇讲了 ,在bean的实例化过程中, 首先 就是通过 FactoryMethod 或者 构造方法 来创建出对象,对应的是AbstractAutowireCapableBeanFactory.doCreateBean 的这部分代码。

image

这篇将 介绍的 是 接下来的这段代码 :

其主要作用 就是 通过 预置好的BeanPostProcessor类 来进行 @Autowired/@Value的属性和方法,@PreDestory / @PostConstruct 的方法 的收集工作, 并且 放到BeanDefinition对象里的容器里 ,为 后续的 依赖注入,以及调用生命周期 方法 做准备。

image

循环所有的BeanPostProcessor类型,如果是MergedBeanDefinitionPostProcessor类型(这个类型的主要就是用来做收集工作的)。

image

1. @Autowired,@Value

负责收集@Autowired,@Value的属性和方法的是AutowiredAnnotationBeanPostProcessor这个类。

点进AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)

image
  1. findAutowiringMetadata(beanName, beanType, null) :收集@Autowired,@Value的属性和方法,封装到InjectionMetadata 对象里
  2. InjectionMetadata .checkConfigMembers(bd) : 将收集好的属性和方法 设置到beanDefinition 里。

1.1 收集@Autowired,@Value的属性和方法

1.1.1 InjectionMetadata 类

内部有targetClass 和 装收集到属性和方法的集合

image

1.1.1.1 InjectedElement

其实就是 jdk反射里的Member对象的包装,Member 又是 Field和Method 对象的 父类.

image

1.1.2. findAutowiringMetadata 开始收集

1.1.2.1 缓存

这里又是一个缓存, 缓存是AutowiredAnnotationBeanPostProcessor中的injectionMetadataCache对象。

private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);

缓存的Key是 beanName或者Class的名称, 所有的bean 收集好的属性和方法都缓存在AutowiredAnnotationBeanPostProcessor对象里的injectionMetadataCache 中。

image

1.1.2.2 缓存里没有,开始收集 buildAutowiringMetadata(clazz)

1.2.2.2.1 属性的收集
image

循环该Class对象的所有 Fields, 然后判断是否存在@autowired/@Value注解且为非静态的。

  1. findAutowiredAnnotation() 查找注解
image

autowiredAnnotationTypes 是AutowiredAnnotationBeanPostProcessor 在构造方法 就 提前内置好的 要处理的注解的 集合

image

AutowiredFieldElement

这个类是InjectedElement的子类,专门用来包装有@Autowired和@Value注解的属性,还多了 @Autowired的required属性的值。

image

所以这段代码的作用是 ,只要是@Autowired和@Value 注解,都可以被收集。如果符合,就创建AutowiredFieldElement对象,加到currElements 中

1.2.2.2.2 方法的收集

有@autowired/@Value注解且为非静态的方法的收集原理 和 收集属性 是一样的:

循环每个方法, 判断是否符合注解, 符合的话将Method 和 @Autowired的required值封装到 AutowiredMethodElement 对象里, 加到 currElements容器里。

image

AutowiredMethodElement类 和 AutowiredFieldElement类 差不多,装Method和Field的区别。同样继承的InjectedElement类。

image
1.2.2.2.3 返回InjectionMetadata对象

将刚才收集到的属性和方法全部加到elements里,

image

然后 new 出InjectionMetadata 对象

image image

1.1.2.3 建立InjectionMetadata 的缓存

包装的 所有带有@Autowired和@Value的属性和方法的 InjectionMetadata 对象创建出来之后, 缓存到AutowiredAnnotationBeanPostProcessor类里的injectionMetadataCache中:{beanName || beanClassName : InjectionMetadata对象},下次从缓存中取。

image

1.1.3 将收集到的属性和方法设置到BeanDefinition里

收集完之后,将InjectionMetadata 对象里收集到的属性和方法 放到BeanDefinition对象里的 externallyManagedConfigMembers 集合中

image image

至此 @Autowired,@Value注解的 方法和 属性全部收集完毕。

2. @Resource

@Resource的收集是由CommonAnnotationBeanPostProcessor类来完成的

点进CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()

image

和 收集 @autowired/ @Value 差不多的流程

image

2.1 先是创建InjectionMetadata 对象

image

2.1.1 判断缓存

image

2.1.2 开始收集 buildResourceMetadata

2.1.2.1 属性

其他的判断分支不用看, 没啥用

image

2.1.2.2 方法

image

2.1.3 返回InjectionMetadata对象

image

2.1.3 建立缓存

image

2.2 将收集到的属性和方法设置到BeanDefinition里

image

3. @PostConstruct和@PreDestroy

这两个注解是用在方法上的,他们的收集功能由CommonAnnotationBeanPostProcessor的父类,InitDestroyAnnotationBeanPostProcessor来完成, 就在CommonAnnotationBeanPostProcessor收集@Resource 的代码 之前,调用了 super.postProcessMergedBeanDefinition().

image image

收集的过程 和 前面哪几个注解的差不多。

3.1 收集 @PostConstruct方法和@PreDestroy方法

收集到的属性会方法LifecycleMetadata对象里,这个对象里面有两个属性专门用来装 有这两个注解的 方法。

image

点进findLifecycleMetadata(beanType)。

3.1.1 缓存

image

3.1.2 开始收集

点进buildLifecycleMetadata(clazz)

循环方法,有@PostConstruct 放到一个集合里,有@PreDestroy注解的放到另一个集合里

image

InitDestroyAnnotationBeanPostProcessor 里的 initAnnotationType,destroyAnnotationType 是在子类CommonAnnotationBeanPostProcessor实例化的时候设置的

image

3.1.3 返回LifecycleMetadata对象

image

3.1.4 建立缓存

image

3.2 将收集到的方法放到BeanDefinition中

  1. 把解析出来的含有@PostConstruct注解的方法添加到 bd的 externallyManagedInitMethods<Method>
  2. 把解析出来的含有@PreDestroy 注解的方法 添加 bd的 externallyManagedDestroyMethods<Method>
image image

4. 总结

收集完了, 以后bean的依赖注入和调用方法 时 就从这里 获取需要处理的属性和方法就行了。

4.1 几个BeanPostProcessor和各自负责的工作:

  1. AutowiredAnnotationBeanPostProcessor : 收集@Autowired,@Value的属性和方法
  2. CommonAnnotationBeanPostProcessor : 收集@Resource
    1. 并调用父类InitDestroyAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()来收集@PostConstruct,@PreDestroy

4.2 BeanDefinition中装收集好的成员的 容器

    @Nullable
    // 装@Autowired,@Value,@Resource注解 的 属性和方法
    private Set<Member> externallyManagedConfigMembers;

    @Nullable
    // 装@PostConstruct注解 的方法
    private Set<String> externallyManagedInitMethods;

    @Nullable
    // 装 有@PreDestroy注解修饰的 方法
    private Set<String> externallyManagedDestroyMethods;

相关文章

网友评论

    本文标题:【Spring源码】10.IOC之@Autowired,@Val

    本文链接:https://www.haomeiwen.com/subject/isawhrtx.html