作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
阶段1、深入多线程
阶段2、深入多线程设计模式
阶段3、深入juc源码解析
码哥源码部分
码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】
码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】
码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】
码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】
打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】
AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition
上一篇说了CommonAnnotationBeanPostProcessor
的处理,处理完了就要轮到AutowiredAnnotationBeanPostProcessor
的处理啦,我们来看看吧。
其实也就是去找Autowired
和Value
注解的方法和属性。
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
findAutowiringMetadata寻找自动装配元数据
和前面的CommonAnnotationBeanPostProcessor
的findLifecycleMetadata
很像吧,先找缓存,没有再创建,都用同步双重检测。
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.
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构建自动装配元数据
会去寻找有Autowired
和Value
注解的属性和方法,也包括自定义的父类的,封装成AutowiredMethodElement
放入集合里。
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())) {//Autowired注解不支持静态方法
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);//查看是否是required的
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();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
ReflectionUtils的doWithLocalFields处理属性
处理所有属性。
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
for (Field field : getDeclaredFields(clazz)) {
try {
fc.doWith(field);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
}
}
}
ReflectionUtils的doWithLocalMethods处理方法
这个跟上个类型,就是处理方法的,处理方法上Autowired
和Value
注解。
public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) {
Method[] methods = getDeclaredMethods(clazz, false);
for (Method method : methods) {
try {
mc.doWith(method);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
}
}
}
FieldCallback的doWith
其实就是个lambda
表达式来处理,找出自动装配的注解,如果存在且非静态的就取出required
,然后封装成AutowiredFieldElement
加入集合。
field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {//Autowired注解不支持静态方法
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);//查看是否是required的
currElements.add(new AutowiredFieldElement(field, required));
}
findAutowiredAnnotation
其实就是查看是否有Autowired
和Value
注解,有的话就返回。
@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的forElements
最后会根据是否有属性和方法有Autowired
和Value
注解,没有就返回InjectionMetadata.EMPTY
,有的话就封装成InjectionMetadata
返回。
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
}
InjectionMetadata的checkConfigMembers
如果集合里有注解的属性和方法,就会讲他们注册到beanDefinition
的集合externallyManagedConfigMembers
中。
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;
}
ApplicationListenerDetector的postProcessMergedBeanDefinition
这个只是记录下名字和是否是单例的映射。
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
this.singletonNames.put(beanName, beanDefinition.isSingleton());
}
总结
其实applyMergedBeanDefinitionPostProcessors
主要做的事就是用处理器把属性和方法上的自动装配的信息记录下来,放到bean
定义里,后面进行填充的时候可以用到,其中就包括CommonAnnotationBeanPostProcessor
的生命周期方法和webService,ejb,Resource
注解信息以及AutowiredAnnotationBeanPostProcessor
的Autowired
和Value
注解信息。