本篇带给大家MergedBeanDefinitionPostProcessor处理器的作用及MergedBeanDefinitionPostProcessor合并Bean定义处理器,该处理器有什么用处?通过源码来查看具体的功能。
环境:Springboot2.3.12RELEASE
主要内容:
MergedBeanDefinitionPostProcessor处理器的作用
MergedBeanDefinitionPostProcessor合并Bean定义处理器,该处理器有什么用处?通过源码来查看具体的功能
这里从创建一个Bean实例开始说起。
1 环境准备@Component
public class PersonDAOImpl implements PersonDAO {
@Override
public void save() {
System.out.println("保存Person信息") ;
}
}
@Service
public class UsersService {
@Autowired
private PersonDAO personDAO ;
public void saveUsers(Users users) {
System.out.println("保存用户信息") ;
}
} 2 创建实例public abstract class AbstractAutowireCapableBeanFactory {
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 在创建实例后调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
}
mbd.postProcessed = true;
}
}
}
} 3 执行合并Bean定义方法public abstract class AbstractAutowireCapableBeanFactory {
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
} 在这里符合要求的BeanPostProcessor对象有:
CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor(这里值列出重点的两个)Common这个主要处理:@PostConstruct和@PreDestroy及@Resource等相关的注解;Autowired主要处理的是:@Autowired和@Value及@Inject注解
上面的准备的类中在UserService中通过@Autowired注入了PersonDAO对象,所以这里我们主要是看下
AutowiredAnnotationBeanPostProcessor处理器。
4 处理执行public class AutowiredAnnotationBeanPostProcessor {
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 查找
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
// 生成缓存使用的Key名称,后续会通过该Key将对应的信息缓存起来
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 从当前的缓存中获取是否存在
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
// 该方法中会判断缓存中是否存在,上面的metadata;以下通过双重检查
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 构建自动装配元信息;通过当前在这处理的class对象查找是否具有@Autowired注解信息(从字段和方法上查找)
metadata = buildAutowiringMetadata(clazz);
// 将查找到的InjectionMetadata缓存起来,在后续填充属性的时候直接通过缓存获取即可
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
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<>();
// 这里通过方法也能知道遍历当前类中的所有字段,检查是否有@Autowired注解
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 在字段上查找@Autowired注解信息
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
// 判断当前的字段是否通过static修饰了
if (Modifier.isStatic(field.getModifiers())) {
return;
}
// 判断是否必须的字段(默认是true,要注入的Bean必须存在)
boolean required = determineRequiredStatus(ann);
// 将查找到的字段信息保存到AutowriedFieldElement中
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 遍历当前class中所有的方法,是否有@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())) {
return;
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
// 遍历当前的类及父类,一直找到父类为Object为止
} while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
// 开始遍历当前的字段(方法)上是否有autowiredAnnotationTypes集合中定义的注解(该集合在构造该对象的时候就添加了)
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
}
public abstract class ReflectionUtils {
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);
}
}
}
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);
}
}
}
} 5 填充属性
在这里的属性填充会利用上面的缓存中之间取值进行属性的注入public class AutowiredAnnotationBeanPostProcessor {
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 这里会直接从缓存中(injectionMetadataCache)获取
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
// 属性的填充注入
metadata.inject(bean, beanName, pvs);
return pvs;
}
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;
}
} 以上就是
MergedBeanDefinitionPostProcessor处理器的作用了。
原文链接:https://www.toutiao.com/a7002388973628801544/
|