【Spring源码系列- IOC】
CommonAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()中一共包含3个方法,上篇文章我们介绍了的第一个方法,它一个父类调用(如下图),其实就是处理@PostConstruct和@PreDestroy这两个注解的
![](https://i-blog.csdnimg.cn/blog_migrate/3a39b49d5acd9b5b37865b4c09217e05.png)
这篇我们继续介绍后面两个方法( ̄∇ ̄)
findResourceMetadata()
在这个方法中会找出beanType所有被@Resource注解标记的字段/方法,并将它们封装到对象InjectionMetadata中
![](https://i-blog.csdnimg.cn/blog_migrate/c1e64332a639df35cf4ca00ff68e0973.png)
方法中先获取对应的beanName来作为缓存的key,然后尝试从缓存中获取注入的元数据对象,对获取到的对象进行判断,如果不需要更新则直接返回;如果需要更新则进行更新,并将返回的metadata对象放入injectionMetadataCache缓存中,缓存的key为beanName,以便后续操作从缓存中取出
buildResourceMetadata()、构建元数据对象
![](https://i-blog.csdnimg.cn/blog_migrate/5181a099ebe93e258049948856507a8e.png)
方法的一开始先判断当前clazz是否是候选class,然后创建InjectedElement集合对象,之后进入了一个do while循环♻️,这个循环会不断获取父类进行注解的识别(仅识别,不会进行属性的注入,具体解析位置同@Autowired),直到当前类为null或者父类为Object.java
循环内主要有两大部分:
第一部分
![](https://i-blog.csdnimg.cn/blog_migrate/005cbcefabfc8ee79ce76089e9e8d040.png)
通过doWithLocalFields()方法查询是否属性字段上有webService、ejb、Resource的属性注解,进行了如下一系列判断:
webService
webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)是对是否加载了"javax.xml.ws.WebServiceRef"进行判断(具体赋值位置如下图)
![](https://i-blog.csdnimg.cn/blog_migrate/eb62c3b66ccc40a0373cbdf48c3a2845.png)
(在注解为Resource时需要注意⚠️:1. 不支持静态属性;2. 如果不想注入某一类型对象,可以将其加入ignoredResourceType中,字段会封装到ResourceElement中)
ejb
接着是对ejbClass != null && field.isAnnotationPresent(ejbClass)的判断(具体赋值位置如下图)
![](https://i-blog.csdnimg.cn/blog_migrate/ebf1c95529293c4093ea53b8efe41d33.png)
Resource
最后是对于field.isAnnotationPresent(Resource.class)的判断,Resource注解一般用在类属性或者setter()方法上声明属性需要自动装配,默认byName的形式,找不到则尝试byType的形式(@Autowired则默认byType的形式注入)
第二部分
通过doWithLocalMethods()方法查询是否有方法上有webService、ejb、Resource的属性注解
![](https://i-blog.csdnimg.cn/blog_migrate/84d52b59615e809b53aecef286aa11cf.png)
最终会获取一个集合elements完成buildResourceMetadata()的逻辑
![](https://i-blog.csdnimg.cn/blog_migrate/fb6f839d036a7916e79f8a59562e4580.png)