学习spring-IOC后置处理器的第三次调用发现一个有意思的点,所以写出来记录一下。
在研究ioc的bean的创建过程,
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean:
// Allow post-processors to modify the merged bean definition.
//允许后置处理器修改合并beanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//第三次后置处理器调用
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
//全部转换成统一格式的BeanPostProcessor的子类MergedBeanDefinitionPostProcessor
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
//调用实际的后置处理方法
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//获取类的生命周期的信息,LifecycleMetadata包含初始化方法和销毁方法信息,将获取的类的初始化方法和销毁方法注册
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
//获取类的注解信息源数据
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
//注册
metadata.checkConfigMembers(beanDefinition);
}
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
最终都是获取InjectionMetadata 。
CommonAnnotationBeanPostProcessor:负责解析@Resource、@WebServiceRef、@EJB三个注解
AutowiredAnnotationBeanPostProcessor:负责@Autowired
AutowiredAnnotationBeanPostProcessor:负责@Persistence
跟踪最终的代码:
/***
* 找到所要注入的类,标记有 @Autowired注解的 field和method 添加到一个list中
* 以list和这个class封装成一个InjectionMetadata
*/
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
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<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
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;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
/***
* 一直循环封装,直到目标类为null或者父类是Object
* -->这里也就说明了如果你在一个子类有@AutoWired注解的 field和method,
* 那么会一直扫描父类,直到扫描到Object才停止
*/
while (targetClass != null && targetClass != Object.class);
//封装找到了的method和field,放到InjectionMetadata
return InjectionMetadata.forElements(elements, clazz);
}
其他注解对应的后置处理器,我也基本跟了一遍最终都是一样的循环和判断条件。
根据while的条件,可知如果你在一个子类有@AutoWired,@Resource等注解修饰, 那么会一直扫描父类,直到扫描到Object才停止,最后将扫描的该类和该类的所有父类的注解放到list中,才会返回。
**最终结论:**一个类会继承父类的注解。但是目前通过这块源码只找到前面提到的这几种,其他注解没有找到。如果后面研究完ioc,再实验一下。