Back to Javatutorial

Spring启动流程(五):执行BeanFactoryPostProcessor

docs/Spring全家桶/Spring源码分析/Spring启动流程/Spring启动流程(五):执行BeanFactoryPostProcessor.md

1.0.021.9 KB
Original Source

ģǼ

4. չ㣺postProcessBeanFactory(beanFactory)

spring ṩչ㣬κιܣʵ֣AbstractApplicationContext postProcessBeanFactory £

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

ǰʹõ ApplicationContext AnnotationConfigApplicationContextûʵ

5. ִ BeanFactoryPostProcessors: invokeBeanFactoryPostProcessors(beanFactory)

BeanFactoryPostProcessor Ϊ beanFactory ĺô޸ beanFactory һЩΪ BeanFactoryPostProcessor ϸԲο spring ֮ BeanFactoryPostProcessors

BeanFactoryPostProcessorἸ㣺

  • BeanFactoryPostProcessor Ϊ֣BeanFactoryPostProcessor BeanDefinitionRegistryPostProcessor
  • BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor
  • ִ BeanDefinitionRegistryPostProcessor ķִ BeanFactoryPostProcessor ķ

˽ЩǸ룬ԲҪֻ£

|-AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(String...)
 |-AbstractApplicationContext#refresh
  |-AbstractApplicationContext#invokeBeanFactoryPostProcessors
   |-PostProcessorRegistrationDelegate
     #invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>)

ֱӿ invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, 
            List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // дڵBeanDefinitionRegistryPostProcessor
    Set<String> processedBeans = new HashSet<>();

    //beanFactoryDefaultListableBeanFactoryBeanDefinitionRegistryʵ࣬Կ϶if
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

        //regularPostProcessors BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

        //registryProcessors BeanDefinitionRegistryPostProcessor
        //BeanDefinitionRegistryPostProcessor չ BeanFactoryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        // ѭbeanFactoryPostProcessors£beanFactoryPostProcessors϶û
        // ΪbeanFactoryPostProcessorsǻֶӵģspringɨ
        // ֶֻannotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)Ż
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // жpostProcessorDzBeanDefinitionRegistryPostProcessor
            // ΪBeanDefinitionRegistryPostProcessor չBeanFactoryPostProcessor
            // ҪжDzBeanDefinitionRegistryPostProcessor, ǵĻֱִ
            // postProcessBeanDefinitionRegistryȻѶװregistryProcessorsȥ
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                //ǵĻװregularPostProcessors
                regularPostProcessors.add(postProcessor);
            }
        }

        // һʱװBeanDefinitionRegistryPostProcessor
        // BeanDefinitionRegistry̳PostProcessorBeanFactoryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // ʵBeanDefinitionRegistryPostProcessorӿڵBeanName
        // springڲṩBeanDefinitionRegistryPostProcessor
        // ԼԼʵֵBeanDefinitionRegistryPostProcessor
        String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
               //ConfigurationClassPostProcessor࣬ҷŵcurrentRegistryProcessors
               //ConfigurationClassPostProcessorǺҪһ࣬ʵ
               //BeanDefinitionRegistryPostProcessorӿڣ
               //BeanDefinitionRegistryPostProcessorӿʵBeanFactoryPostProcessorӿ
               //ConfigurationClassPostProcessorǼҪ, ִ
               //ɨ @Bean@Import@ImportResource ȸֲ
               currentRegistryProcessors.add(beanFactory.getBean(
                   ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
            }
        }

       //
       sortPostProcessors(currentRegistryProcessors, beanFactory);

       //ϲProcessorsΪʲôҪϲΪregistryProcessors
       //װBeanDefinitionRegistryPostProcessor
       //һʼʱspringִֻBeanDefinitionRegistryPostProcessorеķ
       //ִBeanDefinitionRegistryPostProcessorķBeanFactoryProcessorķ
       //ҪѴһУͳһִиķ
       registryProcessors.addAll(currentRegistryProcessors);

       //ΪִConfigurationClassPostProcessorpostProcessBeanDefinitionRegistry
       invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
       //ΪcurrentRegistryProcessorsһʱҪ
       currentRegistryProcessors.clear();

       // ٴθBeanDefinitionRegistryPostProcessorBeanName
       // BeanNameǷѾִйˣûʵOrderedӿ
       // ûбִйҲʵOrderedӿڵĻѶ͵currentRegistryProcessors
       // ͵processedBeans
       // ûʵOrderedӿڵĻﲻݼӵcurrentRegistryProcessors
       // processedBeansУ
       // ſԻǶʵBeanDefinitionRegistryPostProcessorBean
       postProcessorNames = beanFactory.getBeanNamesForType(
              BeanDefinitionRegistryPostProcessor.class, true, false);
       for (String ppName : postProcessorNames) {
           if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
              currentRegistryProcessors.add(beanFactory.getBean(
                  ppName, BeanDefinitionRegistryPostProcessor.class));
              processedBeans.add(ppName);
           }
       }
       //
       sortPostProcessors(currentRegistryProcessors, beanFactory);
       //ϲProcessors
       registryProcessors.addAll(currentRegistryProcessors);
       //ִԶBeanDefinitionRegistryPostProcessor
       invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
       //ʱ
       currentRegistryProcessors.clear();
       // ĴִʵOrderedӿڵBeanDefinitionRegistryPostProcessor
       // ĴִûʵOrderedӿڵBeanDefinitionRegistryPostProcessor
       boolean reiterate = true;
       while (reiterate) {
           reiterate = false;
           postProcessorNames = beanFactory.getBeanNamesForType(
                    BeanDefinitionRegistryPostProcessor.class, true, false);
           for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(
                            ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
           }
           sortPostProcessors(currentRegistryProcessors, beanFactory);
           registryProcessors.addAll(currentRegistryProcessors);
           invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
           currentRegistryProcessors.clear();
       }

       // registryProcessorsװBeanDefinitionRegistryPostProcessor
       // ĴִеķҪٰѸķҲִһ
       invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
       invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        //regularPostProcessorsװBeanFactoryPostProcessorִBeanFactoryPostProcessorķ
        //regularPostProcessorsһ£Dzݵģ
        //ֶֻBeanFactoryPostProcessorŻ
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    //ѭBeanName
    for (String ppName : postProcessorNames) {
        //Beanִйˣ
        if (processedBeans.contains(ppName)) {

        }
        //ʵPriorityOrderedӿڣ뵽priorityOrderedPostProcessors
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory
                .getBean(ppName, BeanFactoryPostProcessor.class));
        }
        //ʵOrderedӿڣ뵽orderedPostProcessorNames
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        //ûʵPriorityOrderedҲûʵOrdered뵽nonOrderedPostProcessorNames
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // priorityOrderedPostProcessorsʵPriorityOrderedӿڵBeanFactoryPostProcessor
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // ִpriorityOrderedPostProcessors
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // ִʵOrderedӿڵBeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> orderedPostProcessors 
            = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(
            postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // ִмûʵPriorityOrderedӿڣҲûʵOrderedӿڵBeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors 
            = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(
                postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    beanFactory.clearMetadataCache();
}

dzdzѣִѭ⼸

  • ִ BeanDefinitionRegistryPostProcessorִ BeanFactoryPostProcessor
  • ִ BeanDefinitionRegistryPostProcessor ˳£
    1. ִв BeanDefinitionRegistryPostProcessor
    2. ִ spring ڲṩģִһdzҪ BeanDefinitionRegistryPostProcessor``ConfigurationClassPostProcessorᴦĿе @ComponentScan``@Component``@Import``@Bean ע⣬ûԶ BeanDefinitionRegistryPostProcessor``BeanFactoryPostProcessor
    3. ִʣµ BeanDefinitionRegistryPostProcessorҲһмص BeanDefinitionRegistryPostProcessor
  • ִ BeanFactoryPostProcessor ˳£
    1. ִʵ PriorityOrdered ӿڵ BeanFactoryPostProcessor
    2. ִʵ Ordered ӿڵ BeanFactoryPostProcessor
    3. ִʣµ BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor ࣬ͬҪִ BeanFactoryPostProcessor ķ

˵ִ BeanDefinitionRegistryPostProcessorִָ PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessorsִ BeanFactoryPostProcessor ִָ BeanFactoryPostProcessor#postProcessBeanFactory

ݺ󣬽ǶϷϸˣ

  1. ִ BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry:
    1. ִпֶ applicationContext.addBeanFactoryPostProcessor ӵ BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry һ£ֶ߲ø÷;
    2. ִ spring ڲṩġʵ PriorityOrdered ӿڵ BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry
    3. ִʵ Ordered ӿδִй BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry
    4. ִδִй BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry
  2. ִ BeanFactoryPostProcessor#postProcessBeanFactory
    1. ִпߵ applicationContext.addBeanFactoryPostProcessor ӵ BeanDefinitionRegistryPostProcessor postProcessBeanFactory һ£ֶ߲ø÷;
    2. ִϴδִйġʵ PriorityOrdered BeanFactoryPostProcessor postProcessBeanFactory
    3. ִϴδִйġʵ Ordered BeanFactoryPostProcessor postProcessBeanFactory
    4. ִϴδִй BeanFactoryPostProcessor postProcessBeanFactory

ԿʵʾΪִBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry BeanFactoryPostProcessor#postProcessBeanFactoryҪעǣBeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor ࣬ڵ BeanFactoryPostProcessor#postProcessBeanFactory ʱ ʵҲ BeanDefinitionRegistryPostProcessor postProcessBeanFactory .

ϵ BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry BeanFactoryPostProcessor#postProcessBeanFactory ִУִЩأͨ demo01ִеĴ£

  1. 1.2 ʱִ ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
  2. 1.4 ʱִ ConfigurationClassPostProcessor#postProcessBeanFactory
  3. 2.4 ʱִ EventListenerMethodProcessor#postProcessBeanFactory

ţDZչʲô

5.1 ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry ִ

һȥԲҪķֻʾջ

AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.String...)
 |-AbstractApplicationContext#refresh
  |-AbstractApplicationContext#invokeBeanFactoryPostProcessors
   |-PostProcessorRegistrationDelegate
      #invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)
    |-PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
     |-ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
      |-ConfigurationClassPostProcessor#processConfigBeanDefinitions

ֱӽ ConfigurationClassPostProcessor#processConfigBeanDefinitions

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    String[] candidateNames = registry.getBeanDefinitionNames();

    //ѭcandidateNames
    for (String beanName : candidateNames) {
    BeanDefinition beanDef = registry.getBeanDefinition(beanName);

    // ڲλǷѾ
    // һ֪ʶä
    // עʱ򣬿ԲConfigurationע⣬
    // ֱʹComponent ComponentScan Import ImportResourceע⣬֮ΪLite
    // Configurationע⣬ͳ֮ΪFull
    // עLite࣬getBean࣬ᷢԭǸ
    // עFull࣬getBean࣬ᷢѾԭǸˣ
    // Ѿcgilb
    if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
            if (logger.isDebugEnabled()) {
                logger.debug(...);
            }
        }
        // жǷΪ࣬
       // 1\.  @Configuration ע  proxyBeanMethods != false ࣬spring Ϊ Full 
       // 2\.  @Configuration ע  proxyBeanMethods == false,
       //   @Component@ComponentScan@Import@ImportResource
       // @Bean ֮һע࣬spring Ϊ Lite 
       // FullLitebeanDefбʶ
       else if (ConfigurationClassUtils
               .checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
           configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
       }
    }

    // ûֱ࣬ӷ
    if (configCandidates.isEmpty()) {
         return;
    }

    // 
    configCandidates.sort((bd1, bd2) -> {
         int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
         int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
         return Integer.compare(i1, i2);
    });

    SingletonBeanRegistry sbr = null;
    // DefaultListableBeanFactoryջʵSingletonBeanRegistryӿڣԿԽ뵽if
    if (registry instanceof SingletonBeanRegistry) {
        sbr = (SingletonBeanRegistry) registry;
        if (!this.localBeanNameGeneratorSet) {
            //springп޸ĬϵbeanʽǿûûԶbeanʽ
            BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                     AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
            if (generator != null) {
                this.componentScanBeanNameGenerator = generator;
                this.importBeanNameGenerator = generator;
            }
        }
    }

    if (this.environment == null) {
         this.environment = new StandardEnvironment();
    }

    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        //࣬˺ܶ£
        //磺@Component@PropertySources@ComponentScans@ImportResourceȵĴ
        parser.parse(candidates);
        parser.validate();

        Set<ConfigurationClass> configClasses
                = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                registry, this.sourceExtractor, this.resourceLoader, this.environment,
                this.importBeanNameGenerator, parser.getImportRegistry());
        }
        // ֱһŰImport࣬@Bean @ImportRosource תBeanDefinition
        this.reader.loadBeanDefinitions(configClasses);
        // configClasses뵽alreadyParsed
        alreadyParsed.addAll(configClasses);

        candidates.clear();
        // עBeanDefinition  candidateNamesбȽ
        // ڵĻ˵µBeanDefinitionע
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
            String[] newCandidateNames = registry.getBeanDefinitionNames();
            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
            Set<String> alreadyParsedClasses = new HashSet<>();
            // ѭalreadyParsed뵽alreadyParsedClasses
            for (ConfigurationClass configurationClass : alreadyParsed) {
                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
            }
            for (String candidateName : newCandidateNames) {
                if (!oldCandidateNames.contains(candidateName)) {
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils
                                .checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                            !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    while (!candidates.isEmpty());

    if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
        sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
    }

    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    }
}

ϷǶ BeanDefinition ϢĽһƣ @Configuration``@PropertySources``@ComponentScans``@ImportResource ȵĴ demo01 ûЩע⣬ǾͲչˣٷ

5.2 ִ ConfigurationClassPostProcessor#postProcessBeanFactory

ConfigurationClassPostProcessor postProcessBeanFactory Ƚϼ򵥣»Ƕ @Configuration ǿ

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // ʡ

    //  ConfigurationClasses ǿ
    enhanceConfigurationClasses(beanFactory);
    beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
    // ʡ

    // ȫࣺ
    ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
    for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
        AbstractBeanDefinition beanDef = entry.getValue();
        // If a @Configuration class gets proxied, always proxy the target class
        beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
        // Set enhanced subclass of the user-specified bean class
        // ǿ
        Class<?> configClass = beanDef.getBeanClass();
        Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
        if (configClass != enhancedClass) {
            beanDef.setBeanClass(enhancedClass);
        }
    }
}

demo01 û @ConfigurationͲչˣٷ

5.3 ִ EventListenerMethodProcessor#postProcessBeanFactory

¼ģֱϴ룺

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    this.beanFactory = beanFactory;
    Map<String, EventListenerFactory> beans 
          = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);

    List<EventListenerFactory> factories = new ArrayList<>(beans.values());
    AnnotationAwareOrderComparator.sort(factories);
    this.eventListenerFactories = factories;
}

Կ spring Уóе EventListenerFactoryȻֵ this.eventListenerFactoriesͲչˡ

5.4 ܽ

Ľ invokeBeanFactoryPostProcessors ִ̣ΪִBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry BeanFactoryPostProcessor#postProcessBeanFactoryִй£

ͨԷ֣invokeBeanFactoryPostProcessors һִ BeanFactoryPostProcessor

  1. ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
  2. ConfigurationClassPostProcessor#postProcessBeanFactory
  3. EventListenerMethodProcessor#postProcessBeanFactory

УConfigurationClassPostProcessor һdzdzҪ BeanFactoryPostProcessorĽһԲο£


ԭӣhttps://my.oschina.net/funcy/blog/4641114 ߸ˮƽд֮ӭָԭףҵתϵ߻Ȩҵתע