• spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor


      接着上文《spring源码阅读(2)-- 容器启动之加载BeanDefinition》,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置beanFactory,例如设置一下装配规则和判断是否需要创建一些指定的bean。

     1   protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
     2         // Tell the internal bean factory to use the context's class loader etc.
     3         beanFactory.setBeanClassLoader(getClassLoader());
     4         beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
     5         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
     6 
     7         // Configure the bean factory with context callbacks.
     8         //添加ApplicationContextAwareProcessor用于处理实现了EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware接口的bean
     9         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    10         //忽略以下bean的依赖注入
    11         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    12         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    13         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    14         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    15         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    16 
    17         // BeanFactory interface not registered as resolvable type in a plain factory.
    18         // MessageSource registered (and found for autowiring) as a bean.
    19         //注册自动装配模式下的特殊依赖,例如被注入的是BeanFactory类型,那么注入的就是beanFactory
    20         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    21         beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    22         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    23         beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    24 
    25         // Detect a LoadTimeWeaver and prepare for weaving, if found.
    26         if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    27             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    28             // Set a temporary ClassLoader for type matching.
    29             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    30         }
    31 
    32         // Register default environment beans.
    33         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    34             beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    35         }
    36         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    37             beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    38         }
    39         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    40             beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    41         }
    42     }

      当设置完beanFactory,接下来就是执行BeanFactoryPostProcessor。BeanFactoryPostProcessor是spring容器启动时暴露给用户的一个扩展点,允许用户在spring创建bean之前做修改或动态添加bean,动态注册bean可以使用BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor。BeanFactoryPostProcessor接口定义如下:

    1  public interface BeanFactoryPostProcessor {
    2 
    3     void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    4 
    5 }

      当我们实现了BeanFactoryPostProcessor,spring是怎么去执行的呢?

      spring容器在执行刷新时,当加载完BeanDefinition和配置好beanFactory时,会进入AbstractApplicationContext.invokeBeanFactoryPostProcessors,方法里首先调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors去执行实现了BeanFactoryPostProcessor的postProcessBeanFactory方法,然后再判断是否新添加了loadTimeWeaver这个bean,如果有,添加LoadTimeWeaverAwareProcessor

     1     protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
     2         PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
     3 
     4         // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
     5         // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
     6         if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
     7             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
     8             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
     9         }
    10     }

      进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,方法里首先判断beanFactory是不是一个bean注册中心,如果是,循环遍历传入的BeanFactoryPostProcessor,判断是否是BeanDefinitionRegistryPostProcessor的实现,如果是,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry,然后保存到一个集合用于在执行完所有的BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法之后,再执行BeanFactoryPostProcessor.postProcessBeanFactory。

      1     public static void invokeBeanFactoryPostProcessors(
      2             ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
      3 
      4         // Invoke BeanDefinitionRegistryPostProcessors first, if any.
      5         Set<String> processedBeans = new HashSet<String>();
      6 
      7         if (beanFactory instanceof BeanDefinitionRegistry) {
      8             BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      9             List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
     10             List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
     11                     new LinkedList<BeanDefinitionRegistryPostProcessor>();
     12 
     13             for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
     14                 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
     15                     BeanDefinitionRegistryPostProcessor registryPostProcessor =
     16                             (BeanDefinitionRegistryPostProcessor) postProcessor;
     17                     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
     18                     registryPostProcessors.add(registryPostProcessor);
     19                 }
     20                 else {
     21                     regularPostProcessors.add(postProcessor);
     22                 }
     23             }
     24 
     25             // Do not initialize FactoryBeans here: We need to leave all regular beans
     26             // uninitialized to let the bean factory post-processors apply to them!
     27             // Separate between BeanDefinitionRegistryPostProcessors that implement
     28             // PriorityOrdered, Ordered, and the rest.
     29             String[] postProcessorNames =
     30                     beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
     31 
     32             // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
     33             List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
     34             for (String ppName : postProcessorNames) {
     35                 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
     36                     priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
     37                     processedBeans.add(ppName);
     38                 }
     39             }
     40             sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
     41             registryPostProcessors.addAll(priorityOrderedPostProcessors);
     42             invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
     43 
     44             // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
     45             postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
     46             List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
     47             for (String ppName : postProcessorNames) {
     48                 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
     49                     orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
     50                     processedBeans.add(ppName);
     51                 }
     52             }
     53             sortPostProcessors(beanFactory, orderedPostProcessors);
     54             registryPostProcessors.addAll(orderedPostProcessors);
     55             invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
     56 
     57             // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
     58             boolean reiterate = true;
     59             while (reiterate) {
     60                 reiterate = false;
     61                 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
     62                 for (String ppName : postProcessorNames) {
     63                     if (!processedBeans.contains(ppName)) {
     64                         BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
     65                         registryPostProcessors.add(pp);
     66                         processedBeans.add(ppName);
     67                         pp.postProcessBeanDefinitionRegistry(registry);
     68                         reiterate = true;
     69                     }
     70                 }
     71             }
     72 
     73             // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
     74             invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
     75             invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
     76         }
     77 
     78         else {
     79             // Invoke factory processors registered with the context instance.
     80             invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
     81         }
     82 
     83         // Do not initialize FactoryBeans here: We need to leave all regular beans
     84         // uninitialized to let the bean factory post-processors apply to them!
     85         String[] postProcessorNames =
     86                 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
     87 
     88         // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
     89         // Ordered, and the rest.
     90         List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
     91         List<String> orderedPostProcessorNames = new ArrayList<String>();
     92         List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
     93         for (String ppName : postProcessorNames) {
     94             if (processedBeans.contains(ppName)) {
     95                 // skip - already processed in first phase above
     96             }
     97             else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
     98                 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
     99             }
    100             else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    101                 orderedPostProcessorNames.add(ppName);
    102             }
    103             else {
    104                 nonOrderedPostProcessorNames.add(ppName);
    105             }
    106         }
    107 
    108         // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    109         sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    110         invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    111 
    112         // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    113         List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    114         for (String postProcessorName : orderedPostProcessorNames) {
    115             orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    116         }
    117         sortPostProcessors(beanFactory, orderedPostProcessors);
    118         invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    119 
    120         // Finally, invoke all other BeanFactoryPostProcessors.
    121         List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    122         for (String postProcessorName : nonOrderedPostProcessorNames) {
    123             nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    124         }
    125         invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    126 
    127         // Clear cached merged bean definitions since the post-processors might have
    128         // modified the original metadata, e.g. replacing placeholders in values...
    129         beanFactory.clearMetadataCache();
    130     }

      invokeBeanFactoryPostProcessors方法里会找出所有的bean,先排序然后再执行相应的方法。从源码可以看得出,先执行的是传进来的BeanFactoryPostProcessor,第二是实现了PriorityOrdered的接口,第三是实现了Ordered接口,最后的就是没有指定顺序的,而实现了BeanDefinitionRegistryPostProcessor的,会先执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。

      至此,spring对BeanFactoryPostProcessor的扩展点已处理完,从源码可以开出,BeanFactoryPostProcessor的处理会触发bean的创建。

  • 相关阅读:
    Linux中文件夹的读、写、执行权限
    限制提权与sudo -s
    shell支持正则:Linux shell判断字符串是否以某些字符开头
    Linux ssh ftp 用户访问权限
    set ff=unix 转换 为 linux 执行shell报bad interpreter:No such file or directory错误
    Sftp服务器搭建和限制用户目录
    ssh 配置文件讲解大全 ssh调试模式 sftp scp strace进行调试 特权分离
    PAM API
    ssh的chroot配置
    PAM详解(一)PAM介绍
  • 原文地址:https://www.cnblogs.com/hanjiehu/p/8671300.html
Copyright © 2020-2023  润新知