spring源码深入分析applyMergedBeanDefinitionPostProcessors接口,这是一个非常重要的接口,其功能是:
有CommonAnnotationBeanPostProcessor 支持了@PostConstruct,@PreDestroy,@Resource注解; 有AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解; 有BeanPostProcessor接口的典型运用,这里要理解这个接口,对类中注解的装配过程。
1、源码入口:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建实例,在内存中开辟空间,但是对象里面的参数还没有赋值
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//CommonAnnotationBeanPostProcessor 支持了@PostConstruct,@PreDestroy,@Resource注解
//AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解
//BeanPostProcessor接口的典型运用,这里要理解这个接口
//对类中注解的装配过程,收集装配。
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
//省略部分代码。。。。。。
}
2、点击进入:applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
//CommonAnnotationBeanPostProcessor 支持了@PostConstruct,@PreDestroy,@Resource注解;AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解。主要对这两个类的处理
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
点击显示:
这里用此类演示:
3、 点击 bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);进入 AutowiredAnnotationBeanPostProcessor 类
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//点击进入
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
4、点击findAutowiringMetadata 方法:
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
// cache里面包装有注解的属性和方法
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 = buildAutowiringMetadata(clazz);
//返回之后放到缓存中,后续会用到
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
点击buildAutowiringMetadata 方法:
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
//定义一个大的最外层的包装类,包装整个类的有@Autowir注解的对象
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {//定义包装类,包装参数和方法有@Autowir的注解的对象
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//寻找属性参数field上面的@Autowired注解并封装成对象
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);
//找到有@Autowired注解的属性和注解的值封装成一个对象
currElements.add(new AutowiredFieldElement(field, required));
}
});
//寻找Method上面的@Autowired注解并封装成对象
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();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
此处发现此内部类的子类:
后面的两行代码可以证明:
currElements.add(new AutowiredFieldElement(field, required));
currElements.add(new AutowiredMethodElement(method, required, pd));
参数演示:
进入 findAutowiredAnnotation 方法:
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
//取出此参数的注解
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
如图:如果符合一个就直接返回
此处就找这两个中的一个:
返回后此处建立映射关系:
这里封装成InjectionMetadata对象返回:
返回后又建立一个对应关系:
5、返后调用 metadata.checkConfigMembers(beanDefinition); 方发,进入InjectionMetadata类
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}
对应赋值操作:
最终有返回到遍历的这里:
到此,关于类上的参数和方法上有 @Autowired注解的收集和保存分享完毕,大家一定要详细阅读,多多思考定会早日掌握。