飞奔的炮台 发表于 2021-9-9 10:49:27

Springboot启动过程中的这个BeanPostProcessor,你知道干什么的吗

本篇带给大家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/

http://www.zzvips.com/article/190410.html
页: [1]
查看完整版本: Springboot启动过程中的这个BeanPostProcessor,你知道干什么的吗