评论

收藏

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

编程语言 编程语言 发布于:2021-09-09 10:49 | 阅读数:600 | 评论:0

本篇带给大家MergedBeanDefinitionPostProcessor处理器的作用及MergedBeanDefinitionPostProcessor合并Bean定义处理器,该处理器有什么用处?通过源码来查看具体的功能。
DSC0000.png

环境: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/

关注下面的标签,发现更多相似文章