环境: Springboot 2.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/
查看更多关于Springboot启动过程中的这个BeanPostProcessor,你知道干什么的吗的详细内容...