好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

环境: 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,你知道干什么的吗的详细内容...

  阅读:17次