美文网首页spring
invokeBeanFactoryPostProcessors分

invokeBeanFactoryPostProcessors分

作者: loveFXX | 来源:发表于2019-10-23 10:08 被阅读0次

    Bean工厂后置处理器分析

    执行链

    AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)
    AbstractApplicationContext#refresh
    AbstractApplicationContext#invokeBeanFactoryPostProcessors
    执行到这步beanFactory的beanFactoryPostProcessors为空(这里通过api直接提供的才会有值,
    AnnotationConfigApplicationContext.addBeanFactoryPostProcessor( );,一般不会这样做)


    BeanFactory工厂.png

    PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>)
    PostProcessorRegistrationDelegate .invokeBeanFactoryPostProcessors()方法

    final class PostProcessorRegistrationDelegate {
    
        public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<>();
    
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                // Do not initialize FactoryBeans here: We need to leave all regular beans
                // uninitialized to let the bean factory post-processors apply to them!
                // Separate between BeanDefinitionRegistryPostProcessors that implement
                // PriorityOrdered, Ordered, and the rest.
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
    
                // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
                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);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
    
                // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
                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();
                }
                // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
                invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
            }
    
            else {
                // Invoke factory processors registered with the context instance.
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
            }
    
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
            List<String> orderedPostProcessorNames = new ArrayList<>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<>();
            for (String ppName : postProcessorNames) {
                if (processedBeans.contains(ppName)) {
                    // skip - already processed in first phase above
                }
                else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            sortPostProcessors(orderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // Finally, invoke all other BeanFactoryPostProcessors.
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
            // Clear cached merged bean definitions since the post-processors might have
            // modified the original metadata, e.g. replacing placeholders in values...
            beanFactory.clearMetadataCache();
        }
    }
    

    实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered的类

    --------------------就是ConfigurationClassPostProcessor
    14~24 beanFactoryPostProcessors为空将不会处理
    currentRegistryProcessors 当前的,使用策略模式。分别执行这三种不相同的实现类(实现PriorityOrdered的、Ordered的、其他的BeanDefinitionRegistryPostProcessor),执行之后会被清空clear
    registryProcessors 集合是存放BeanDefinitionRegistryPostProcessor的实现类,并在这三种执行后执行postProcessBeanFactory()方法
    根据BeanDefinitionRegistryPostProcessor类从BeanDefinitionMap匹配得到postProcessorNames
    此时获取一个ConfigurationClassPostProcessor类(spring创建Bean工厂时,BeanDefinitionMap里面初始化了6个beandefinition,appConfig类是register注册进去的),由于ConfigurationClassPostProcessor也实现了PriorityOrdered接口,所以当检查是否符合PriorityOrdered的子类时,条件成立最终得到ConfigurationClassPostProcessor类并添加到currentRegistryProcessors集合,processedBeans.add(ppName)这个集合是得到的ConfigurationClassPostProcessor类将会被执行的,防止重复执行

    BeanDefinitionRegistryPostProcessor获取.png
    执行步骤包括排序,添加,执行,清除
    主要步骤是执行invokeBeanDefinitionRegistryPostProcessors方法,包括类的扫描,import等添加其他类到beanDefinitionMap中
    invokeBeanDefinitionRegistryPostProcessors()
        private static void invokeBeanDefinitionRegistryPostProcessors(
                Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    
            for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanDefinitionRegistry(registry);
            }
        }
    

    processConfigBeanDefinitions()方法

    经过调用链ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry执行到processConfigBeanDefinitions()方法

        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
            int registryId = System.identityHashCode(registry);
            if (this.registriesPostProcessed.contains(registryId)) {
                throw new IllegalStateException(
                        "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
            }
            if (this.factoriesPostProcessed.contains(registryId)) {
                throw new IllegalStateException(
                        "postProcessBeanFactory already called on this post-processor against " + registry);
            }
            this.registriesPostProcessed.add(registryId);
    
            processConfigBeanDefinitions(registry);
        }
    

    ConfigurationClassPostProcessor#processConfigBeanDefinitions

    /**
         * Build and validate a configuration model based on the registry of
         * {@link Configuration} classes.
         */
        public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
            List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
            String[] candidateNames = registry.getBeanDefinitionNames();
    
            for (String beanName : candidateNames) {
                BeanDefinition beanDef = registry.getBeanDefinition(beanName);
                if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
                        ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
                    }
                }
                else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                    configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
                }
            }
    
            // Return immediately if no @Configuration classes were found
            if (configCandidates.isEmpty()) {
                return;
            }
    
            // Sort by previously determined @Order value, if applicable
            configCandidates.sort((bd1, bd2) -> {
                int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
                int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
                return Integer.compare(i1, i2);
            });
    
            // Detect any custom bean name generation strategy supplied through the enclosing application context
            SingletonBeanRegistry sbr = null;
            if (registry instanceof SingletonBeanRegistry) {
                sbr = (SingletonBeanRegistry) registry;
                if (!this.localBeanNameGeneratorSet) {
                    BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
                    if (generator != null) {
                        this.componentScanBeanNameGenerator = generator;
                        this.importBeanNameGenerator = generator;
                    }
                }
            }
    
            if (this.environment == null) {
                this.environment = new StandardEnvironment();
            }
    
            // Parse each @Configuration class
            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 {
                parser.parse(candidates);
                parser.validate();
    
                Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
                configClasses.removeAll(alreadyParsed);
    
                // Read the model and create bean definitions based on its content
                if (this.reader == null) {
                    this.reader = new ConfigurationClassBeanDefinitionReader(
                            registry, this.sourceExtractor, this.resourceLoader, this.environment,
                            this.importBeanNameGenerator, parser.getImportRegistry());
                }
                this.reader.loadBeanDefinitions(configClasses);
                alreadyParsed.addAll(configClasses);
    
                candidates.clear();
                if (registry.getBeanDefinitionCount() > candidateNames.length) {
                    String[] newCandidateNames = registry.getBeanDefinitionNames();
                    Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
                    Set<String> alreadyParsedClasses = new HashSet<>();
                    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());
    
            // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
            if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
                sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
            }
    
            if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
                // Clear cache in externally provided MetadataReaderFactory; this is a no-op
                // for a shared cache since it'll be cleared by the ApplicationContext.
                ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
            }
        }
    

    配置类是full或lite processConfigBeanDefinitions9~20

    ConfigurationClassPostProcessor#processConfigBeanDefinitions方法,对candidateNames集合(共有七个,此时还没有扫描)中beandefinition进行遍历,首先是isFullConfigurationClass或isLiteConfigurationClass方法,如果条件成立返回true说明已经被解析过。


    processConfig.png

    CONFIGURATION_CLASS_FULL = "full";
    CONFIGURATION_CLASS_ATTRIBUTE是 org.springframework.context.annotation.ConfigurationClassPostProcessor.
    configurationClass

        public static boolean isFullConfigurationClass(BeanDefinition beanDef) {
            return CONFIGURATION_CLASS_FULL.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
        }
    
        public static boolean isLiteConfigurationClass(BeanDefinition beanDef) {
                    //CONFIGURATION_CLASS_LITE="lite"
            return CONFIGURATION_CLASS_LITE.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
        }
    

    checkConfigurationClassCandidate()检查方法,主要就是isFullConfigurationCandidate和isLiteConfigurationCandidate对BeanDefinition 进行设置setAttribute值。对isFullConfigurationCandidate判断,带有Configuration注解,设置full。对
    isLiteConfigurationCandidate判断,Component,ComponentScan,Import,ImportResource注解任意一个,对属性设置为lite
    ConfigurationClassUtils#checkConfigurationClassCandidate

        private static final Set<String> candidateIndicators = new HashSet<>(8);
        static {
            candidateIndicators.add(Component.class.getName());
            candidateIndicators.add(ComponentScan.class.getName());
            candidateIndicators.add(Import.class.getName());
            candidateIndicators.add(ImportResource.class.getName());
        }
            
        public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
            String className = beanDef.getBeanClassName();
            if (className == null || beanDef.getFactoryMethodName() != null) {
                return false;
            }
            AnnotationMetadata metadata;
            if (beanDef instanceof AnnotatedBeanDefinition &&
                    className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
                // Can reuse the pre-parsed metadata from the given BeanDefinition...
                metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
            }
            else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
                // Check already loaded Class if present...
                // since we possibly can't even load the class file for this Class.
                Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
                metadata = new StandardAnnotationMetadata(beanClass, true);
            }
            else {
                try {
                    MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
                    metadata = metadataReader.getAnnotationMetadata();
                }
                catch (IOException ex) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex);
                    }
                    return false;
                }
            }
    
            if (isFullConfigurationCandidate(metadata)) {
                beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
            }
            else if (isLiteConfigurationCandidate(metadata)) {
                beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
            }
            else {
                return false;
            }
    
            Integer order = getOrder(metadata);
            if (order != null) {
                beanDef.setAttribute(ORDER_ATTRIBUTE, order);
            }
    
            return true;
        }
            
    
         public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
            return metadata.isAnnotated(Configuration.class.getName());
        }
        
          public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
            // Do not consider an interface or an annotation...
            if (metadata.isInterface()) {
                return false;
            }
    
            // Any of the typical annotations found?
            for (String indicator : candidateIndicators) {
                if (metadata.isAnnotated(indicator)) {
                    return true;
                }
            }
    
            // Finally, let's look for @Bean methods...
            try {
                return metadata.hasAnnotatedMethods(Bean.class.getName());
            }
            catch (Throwable ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
                }
                return false;
            }
        }
    
    

    ConfigurationClassParser类解析配置类 processConfigBeanDefinitions方法51~106

    parser.parse(candidates)调用链
    ConfigurationClassParser#parse(Set<BeanDefinitionHolder>)
    ConfigurationClassParser#parse(AnnotationMetadata, String)
    ConfigurationClassParser#processConfigurationClass

    ConfigurationClassParser .class

    class ConfigurationClassParser {
           public void parse(Set<BeanDefinitionHolder> configCandidates) {
            this.deferredImportSelectors = new LinkedList<>();
    
            for (BeanDefinitionHolder holder : configCandidates) {
                BeanDefinition bd = holder.getBeanDefinition();
                try {
                    if (bd instanceof AnnotatedBeanDefinition) {
                        parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
                    }
                    else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
                        parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
                    }
                    else {
                        parse(bd.getBeanClassName(), holder.getBeanName());
                    }
                }
                catch (BeanDefinitionStoreException ex) {
                    throw ex;
                }
                catch (Throwable ex) {
                    throw new BeanDefinitionStoreException(
                            "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
                }
            }
    
            processDeferredImportSelectors();//
        }
    
           protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
            processConfigurationClass(new ConfigurationClass(metadata, beanName));
        }
     
           protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
            if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
                return;
            }
    
            ConfigurationClass existingClass = this.configurationClasses.get(configClass);
            if (existingClass != null) {
                if (configClass.isImported()) {
                    if (existingClass.isImported()) {
                        existingClass.mergeImportedBy(configClass);
                    }
                    // Otherwise ignore new imported config class; existing non-imported class overrides it.
                    return;
                }
                else {
                    // Explicit bean definition found, probably replacing an import.
                    // Let's remove the old one and go with the new one.
                    this.configurationClasses.remove(configClass);
                    this.knownSuperclasses.values().removeIf(configClass::equals);
                }
            }
    
            // Recursively process the configuration class and its superclass hierarchy.
            SourceClass sourceClass = asSourceClass(configClass);
            do {
                sourceClass = doProcessConfigurationClass(configClass, sourceClass);
            }
            while (sourceClass != null);
    
            this.configurationClasses.put(configClass, configClass);
        }
    
           protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
                throws IOException {
    
            // Recursively process any member (nested) classes first
            processMemberClasses(configClass, sourceClass);
    
            // Process any @PropertySource annotations
            for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
                    sourceClass.getMetadata(), PropertySources.class,
                    org.springframework.context.annotation.PropertySource.class)) {
                if (this.environment instanceof ConfigurableEnvironment) {
                    processPropertySource(propertySource);
                }
                else {
                    logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                            "]. Reason: Environment must implement ConfigurableEnvironment");
                }
            }
    
            // Process any @ComponentScan annotations
            Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
                    sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
            if (!componentScans.isEmpty() &&
                    !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
                for (AnnotationAttributes componentScan : componentScans) {
                    // The config class is annotated with @ComponentScan -> perform the scan immediately
                    Set<BeanDefinitionHolder> scannedBeanDefinitions =
                            this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
                    // Check the set of scanned definitions for any further config classes and parse recursively if needed
                    for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                        BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                        if (bdCand == null) {
                            bdCand = holder.getBeanDefinition();
                        }
                        if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                            parse(bdCand.getBeanClassName(), holder.getBeanName());
                        }
                    }
                }
            }
    
            // Process any @Import annotations
            processImports(configClass, sourceClass, getImports(sourceClass), true);
    
            // Process any @ImportResource annotations
            AnnotationAttributes importResource =
                    AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
            if (importResource != null) {
                String[] resources = importResource.getStringArray("locations");
                Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
                for (String resource : resources) {
                    String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                    configClass.addImportedResource(resolvedResource, readerClass);
                }
            }
    
            // Process individual @Bean methods
            Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
            for (MethodMetadata methodMetadata : beanMethods) {
                configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
            }
    
            // Process default methods on interfaces
            processInterfaces(configClass, sourceClass);
    
            // Process superclass, if any
            if (sourceClass.getMetadata().hasSuperClass()) {
                String superclass = sourceClass.getMetadata().getSuperClassName();
                if (superclass != null && !superclass.startsWith("java") &&
                        !this.knownSuperclasses.containsKey(superclass)) {
                    this.knownSuperclasses.put(superclass, configClass);
                    // Superclass found, return its annotation metadata and recurse
                    return sourceClass.getSuperClass();
                }
            }
    
            // No superclass -> processing is complete
            return null;
        }
    }
    

    最终调到doProcessConfigurationClass方法,依次处理processMemberClasses ,@PropertySource注解,@ComponentScan注解,@Import注解,@ImportResource注解,@Bean方法,processInterfaces,superclass。
    不添加到ConfigurationClass中:@PropertySource注解 @ComponentScan
    @ComponentScan注解扫描

    public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
            ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
                    componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
    
            Class<问号 extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
            boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
            scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
                    BeanUtils.instantiateClass(generatorClass));
    
            ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
            if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
                scanner.setScopedProxyMode(scopedProxyMode);
            }
            else {
                Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
                scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
            }
    
            scanner.setResourcePattern(componentScan.getString("resourcePattern"));
    
            for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
                for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                    scanner.addIncludeFilter(typeFilter);
                }
            }
            for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
                for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                    scanner.addExcludeFilter(typeFilter);
                }
            }
    
            boolean lazyInit = componentScan.getBoolean("lazyInit");
            if (lazyInit) {
                scanner.getBeanDefinitionDefaults().setLazyInit(true);
            }
    
            Set<String> basePackages = new LinkedHashSet<>();
            String[] basePackagesArray = componentScan.getStringArray("basePackages");
            for (String pkg : basePackagesArray) {
                String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
                        ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
                Collections.addAll(basePackages, tokenized);
            }
            for (Class<问号> clazz : componentScan.getClassArray("basePackageClasses")) {
                basePackages.add(ClassUtils.getPackageName(clazz));
            }
            if (basePackages.isEmpty()) {
                basePackages.add(ClassUtils.getPackageName(declaringClass));
            }
    
            scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
                @Override
                protected boolean matchClassName(String className) {
                    return declaringClass.equals(className);
                }
            });
            return scanner.doScan(StringUtils.toStringArray(basePackages));
        }
    
    ComponentScanAnnotationParser#parse.png

    得到componentScan扫描路径,然后进行scanner.doScan()方法调用

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
            Assert.notEmpty(basePackages, "At least one base package must be specified");
            Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
            for (String basePackage : basePackages) {
                Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
                for (BeanDefinition candidate : candidates) {
                    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                    candidate.setScope(scopeMetadata.getScopeName());
                    String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                    if (candidate instanceof AbstractBeanDefinition) {
                        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                    }
                    if (candidate instanceof AnnotatedBeanDefinition) {
                        AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                    }
                    if (checkCandidate(beanName, candidate)) {
                        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                        definitionHolder =
                                AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                        beanDefinitions.add(definitionHolder);
                        registerBeanDefinition(definitionHolder, this.registry);
                    }
                }
            }
            return beanDefinitions;
        }
    
    
    

    ClassPathScanningCandidateComponentProvider#findCandidateComponents

        public Set<BeanDefinition> findCandidateComponents(String basePackage) {
            if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
                return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
            }
            else {
                return scanCandidateComponents(basePackage);
            }
        }
    

    ClassPathScanningCandidateComponentProvider#scanCandidateComponents

    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
            Set<BeanDefinition> candidates = new LinkedHashSet<>();
            try {
                String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                        resolveBasePackage(basePackage) + '/' + this.resourcePattern;
                Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
                boolean traceEnabled = logger.isTraceEnabled();
                boolean debugEnabled = logger.isDebugEnabled();
                for (Resource resource : resources) {
                    if (traceEnabled) {
                        logger.trace("Scanning " + resource);
                    }
                    if (resource.isReadable()) {
                        try {
                            MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                            if (isCandidateComponent(metadataReader)) {
                                ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                                sbd.setResource(resource);
                                sbd.setSource(resource);
                                if (isCandidateComponent(sbd)) {
                                    if (debugEnabled) {
                                        logger.debug("Identified candidate component class: " + resource);
                                    }
                                    candidates.add(sbd);
                                }
                                else {
                                    if (debugEnabled) {
                                        logger.debug("Ignored because not a concrete top-level class: " + resource);
                                    }
                                }
                            }
                            else {
                                if (traceEnabled) {
                                    logger.trace("Ignored because not matching any filter: " + resource);
                                }
                            }
                        }
                        catch (Throwable ex) {
                            throw new BeanDefinitionStoreException(
                                    "Failed to read candidate component class: " + resource, ex);
                        }
                    }
                    else {
                        if (traceEnabled) {
                            logger.trace("Ignored because not readable: " + resource);
                        }
                    }
                }
            }
            catch (IOException ex) {
                throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
            }
            return candidates;
        }
    
    findCandidateComponents.png

    扫描路径完成后得到的ScannedGenericBeanDefinition类型的BeanDefinition放到set集合中,然后进行遍历设置默认值
    ClassPathBeanDefinitionScanner#postProcessBeanDefinition

        protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
            beanDefinition.applyDefaults(this.beanDefinitionDefaults);
            if (this.autowireCandidatePatterns != null) {
                beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
            }
        }
    

    AbstractBeanDefinition#applyDefaults

        public void applyDefaults(BeanDefinitionDefaults defaults) {
            setLazyInit(defaults.isLazyInit());
            setAutowireMode(defaults.getAutowireMode());
            setDependencyCheck(defaults.getDependencyCheck());
            setInitMethodName(defaults.getInitMethodName());
            setEnforceInitMethod(false);
            setDestroyMethodName(defaults.getDestroyMethodName());
            setEnforceDestroyMethod(false);
        }
    

    AnnotationConfigUtils#processCommonDefinitionAnnotations(AnnotatedBeanDefinition)

    public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
            processCommonDefinitionAnnotations(abd, abd.getMetadata());
        }
    
        static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
            AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
            if (lazy != null) {
                abd.setLazyInit(lazy.getBoolean("value"));
            }
            else if (abd.getMetadata() != metadata) {
                lazy = attributesFor(abd.getMetadata(), Lazy.class);
                if (lazy != null) {
                    abd.setLazyInit(lazy.getBoolean("value"));
                }
            }
    
            if (metadata.isAnnotated(Primary.class.getName())) {
                abd.setPrimary(true);
            }
            AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
            if (dependsOn != null) {
                abd.setDependsOn(dependsOn.getStringArray("value"));
            }
    
            if (abd instanceof AbstractBeanDefinition) {
                AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
                AnnotationAttributes role = attributesFor(metadata, Role.class);
                if (role != null) {
                    absBd.setRole(role.getNumber("value").intValue());
                }
                AnnotationAttributes description = attributesFor(metadata, Description.class);
                if (description != null) {
                    absBd.setDescription(description.getString("value"));
                }
            }
        }
    

    设置默认值之后,如果BeanDefinitionRegistry不存在这个beandefinition,将会注册进去。遍历完成功会放到bean工厂中,并返回
    Set<BeanDefinitionHolder>集合。返回的beandefinition会被遍历查看通过ConfigurationClassUtils#
    checkConfigurationClassCandidate检查是否是配置类

    processImports

    有三种import形式

    1. ImportSelector
      通过调用ImportSelector的实现类的selectImports方法,得到类路径数组。之后解析成SourceClass。

    2.ImportBeanDefinitionRegistrar
    结果存储到configClass中
    3.import

    private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
                Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
    
            if (importCandidates.isEmpty()) {
                return;
            }
    
            if (checkForCircularImports && isChainedImportOnStack(configClass)) {
                this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
            }
            else {
                this.importStack.push(configClass);
                try {
                    for (SourceClass candidate : importCandidates) {
                        if (candidate.isAssignable(ImportSelector.class)) {
                            // Candidate class is an ImportSelector -> delegate to it to determine imports
                            Class<?> candidateClass = candidate.loadClass();
                            ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
                            ParserStrategyUtils.invokeAwareMethods(
                                    selector, this.environment, this.resourceLoader, this.registry);
                            if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
                                this.deferredImportSelectors.add(
                                        new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
                            }
                            else {
                                String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                                Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
                                processImports(configClass, currentSourceClass, importSourceClasses, false);
                            }
                        }
                        else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
                            // Candidate class is an ImportBeanDefinitionRegistrar ->
                            // delegate to it to register additional bean definitions
                            Class<?> candidateClass = candidate.loadClass();
                            ImportBeanDefinitionRegistrar registrar =
                                    BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
                            ParserStrategyUtils.invokeAwareMethods(
                                    registrar, this.environment, this.resourceLoader, this.registry);
                            configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
                        }
                        else {
                            // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
                            // process it as an @Configuration class
                            this.importStack.registerImport(
                                    currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
                            processConfigurationClass(candidate.asConfigClass(configClass));
                        }
                    }
                }
                catch (BeanDefinitionStoreException ex) {
                    throw ex;
                }
                catch (Throwable ex) {
                    throw new BeanDefinitionStoreException(
                            "Failed to process import candidates for configuration class [" +
                            configClass.getMetadata().getClassName() + "]", ex);
                }
                finally {
                    this.importStack.pop();
                }
            }
        }
    

    返回的结果放置到this.configurationClasses.put(configClass, configClass);
    ConfigurationClassParser#parse(Set<BeanDefinitionHolder>)最后处理deferredImportSelectors延迟import

    parser.validate();

    public void validate() {
            for (ConfigurationClass configClass : this.configurationClasses.keySet()) {
                configClass.validate(this.problemReporter);
            }
        }
    

    ConfigurationClass#validate

    public void validate(ProblemReporter problemReporter) {
            // A configuration class may not be final (CGLIB limitation)
            if (getMetadata().isAnnotated(Configuration.class.getName())) {
                if (getMetadata().isFinal()) {
                    problemReporter.error(new FinalConfigurationProblem());
                }
            }
    
            for (BeanMethod beanMethod : this.beanMethods) {
                beanMethod.validate(problemReporter);
            }
        }
    

    this.reader.loadBeanDefinitions(configClasses)
    对configClasses数据进行加载。对配置类进行candidates集合处理后,对配置类进行了解析(包括扫描和import等的处理),解析出来5个,然后进行this.reader.loadBeanDefinitions(configClasses) 的加载


    parse.png

    ConfigurationClassBeanDefinitionReader#loadBeanDefinitions

    public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
            TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
            for (ConfigurationClass configClass : configurationModel) {
                loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
            }
        }
         private void loadBeanDefinitionsForConfigurationClass(
                ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
    
            if (trackedConditionEvaluator.shouldSkip(configClass)) {
                String beanName = configClass.getBeanName();
                if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
                    this.registry.removeBeanDefinition(beanName);
                }
                this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
                return;
            }
    
            if (configClass.isImported()) {
                registerBeanDefinitionForImportedConfigurationClass(configClass);
            }
            for (BeanMethod beanMethod : configClass.getBeanMethods()) {
                loadBeanDefinitionsForBeanMethod(beanMethod);
            }
    
            loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
            loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
        }
    
    private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
            AnnotationMetadata metadata = configClass.getMetadata();
            AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
    
            ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
            configBeanDef.setScope(scopeMetadata.getScopeName());
            String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
            AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
    
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
            configClass.setBeanName(configBeanName);
    
            if (logger.isDebugEnabled()) {
                logger.debug("Registered bean definition for imported class '" + configBeanName + "'");
            }
        }
    
    /**
         * Read the given {@link BeanMethod}, registering bean definitions
         * with the BeanDefinitionRegistry based on its contents.
         */
        private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
            ConfigurationClass configClass = beanMethod.getConfigurationClass();
            MethodMetadata metadata = beanMethod.getMetadata();
            String methodName = metadata.getMethodName();
    
            // Do we need to mark the bean as skipped by its condition?
            if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
                configClass.skippedBeanMethods.add(methodName);
                return;
            }
            if (configClass.skippedBeanMethods.contains(methodName)) {
                return;
            }
    
            AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
            Assert.state(bean != null, "No @Bean annotation attributes");
    
            // Consider name and any aliases
            List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
            String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
    
            // Register aliases even when overridden
            for (String alias : names) {
                this.registry.registerAlias(beanName, alias);
            }
    
            // Has this effectively been overridden before (e.g. via XML)?
            if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
                if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
                    throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
                            beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
                            "' clashes with bean name for containing configuration class; please make those names unique!");
                }
                return;
            }
    
            ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
            beanDef.setResource(configClass.getResource());
            beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
    
            if (metadata.isStatic()) {
                // static @Bean method
                beanDef.setBeanClassName(configClass.getMetadata().getClassName());
                beanDef.setFactoryMethodName(methodName);
            }
            else {
                // instance @Bean method
                beanDef.setFactoryBeanName(configClass.getBeanName());
                beanDef.setUniqueFactoryMethodName(methodName);
            }
            beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
            beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
    
            AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
    
            Autowire autowire = bean.getEnum("autowire");
            if (autowire.isAutowire()) {
                beanDef.setAutowireMode(autowire.value());
            }
    
            String initMethodName = bean.getString("initMethod");
            if (StringUtils.hasText(initMethodName)) {
                beanDef.setInitMethodName(initMethodName);
            }
    
            String destroyMethodName = bean.getString("destroyMethod");
            beanDef.setDestroyMethodName(destroyMethodName);
    
            // Consider scoping
            ScopedProxyMode proxyMode = ScopedProxyMode.NO;
            AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
            if (attributes != null) {
                beanDef.setScope(attributes.getString("value"));
                proxyMode = attributes.getEnum("proxyMode");
                if (proxyMode == ScopedProxyMode.DEFAULT) {
                    proxyMode = ScopedProxyMode.NO;
                }
            }
    
            // Replace the original bean definition with the target one, if necessary
            BeanDefinition beanDefToRegister = beanDef;
            if (proxyMode != ScopedProxyMode.NO) {
                BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
                        new BeanDefinitionHolder(beanDef, beanName), this.registry,
                        proxyMode == ScopedProxyMode.TARGET_CLASS);
                beanDefToRegister = new ConfigurationClassBeanDefinition(
                        (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
            }
    
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",
                        configClass.getMetadata().getClassName(), beanName));
            }
            this.registry.registerBeanDefinition(beanName, beanDefToRegister);
        }
    
    
        private void loadBeanDefinitionsFromImportedResources(
                Map<String, Class<? extends BeanDefinitionReader>> importedResources) {
    
            Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<>();
    
            importedResources.forEach((resource, readerClass) -> {
                // Default reader selection necessary?
                if (BeanDefinitionReader.class == readerClass) {
                    if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) {
                        // When clearly asking for Groovy, that's what they'll get...
                        readerClass = GroovyBeanDefinitionReader.class;
                    }
                    else {
                        // Primarily ".xml" files but for any other extension as well
                        readerClass = XmlBeanDefinitionReader.class;
                    }
                }
    
                BeanDefinitionReader reader = readerInstanceCache.get(readerClass);
                if (reader == null) {
                    try {
                        // Instantiate the specified BeanDefinitionReader
                        reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
                        // Delegate the current ResourceLoader to it if possible
                        if (reader instanceof AbstractBeanDefinitionReader) {
                            AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader);
                            abdr.setResourceLoader(this.resourceLoader);
                            abdr.setEnvironment(this.environment);
                        }
                        readerInstanceCache.put(readerClass, reader);
                    }
                    catch (Throwable ex) {
                        throw new IllegalStateException(
                                "Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
                    }
                }
    
                // TODO SPR-6310: qualify relative path locations as done in AbstractContextLoader.modifyLocations
                reader.loadBeanDefinitions(resource);
            });
        }
    
        private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
            registrars.forEach((registrar, metadata) ->
                    registrar.registerBeanDefinitions(metadata, this.registry));
        }
    

    返回的结果中beandefinition放到bean工厂方式
    1.isImported 通过this.registry.registerBeanDefinition();
    2.getBeanMethods通过this.registry.registerBeanDefinition();
    3.ImportedResources通过reader.loadBeanDefinitions(resource);
    4.ImportBeanDefinitionRegistrars通过registrar.registerBeanDefinitions(metadata, this.registry)

    清除

    回到最初方法invokeBeanDefinitionRegistryPostProcessors,之后将会清空执行过的currentRegistryProcessors集合


    ConfigurationClassPostProcessor执行.png

    实现了BeanDefinitionRegistryPostProcessor和Ordered的类

    再次获取BeanDefinitionRegistryPostProcessor实现类且实现了Ordered类,此时是在扫描之后,用户可以自定义添加BeanDefinitionRegistryPostProcessor,然后执行与之前实现PriorityOrdered相同的步骤


    BeanDefinitionRegistryPostProcessor再次获取.png

    没有实现Ordered和PriorityOrdered的,但是实现了BeanDefinitionRegistryPostProcessor的类

    Mybatis是在这里实现的
    此时myBeanDefinitionRegistryPostProcessor这个自定义并没有实现Ordered接口,所以processedBeans集合只有一个,经过这步这个自定义的myBeanDefinitionRegistryPostProcessor将会被处理,并添加到processedBeans集合,dubbo应该是这里的应用。然后执行与实现了PriorityOrdered相同的操作流程
    while (reiterate) reiterate被设置为true意义是,可能在执行方法后还会被注册新的BeanDefinition


    处理其他BeanDefinitionRestryPostProcessor.png

    找到这些BeanDefinitionRegistryPostProcessor实现类之后将会执行invokeBeanFactoryPostProcessors

    到这里spring已经执行完所有的BeanDefinitionRegistryPostProcessors,包括三种:
    1.api(new)
    2.内置(spring自己put的)
    3.程序员提供的(程序员自己往beandefinitionMap中put的)
    invokeBeanFactoryPostProcessors方法参数:
    1.registryProcessors api提供的实现BeanDefinitionRegistryPostProcessors的,内置,程序员提供的
    2.regularPostProcessors只会执行api提供的且没有实现BeanDefinitionRegistryPostProcessors的
    ConfigurationClassPostProcessor#postProcessBeanFactory

        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            int factoryId = System.identityHashCode(beanFactory);
            if (this.factoriesPostProcessed.contains(factoryId)) {
                throw new IllegalStateException(
                        "postProcessBeanFactory already called on this post-processor against " + beanFactory);
            }
            this.factoriesPostProcessed.add(factoryId);
            if (!this.registriesPostProcessed.contains(factoryId)) {
                // BeanDefinitionRegistryPostProcessor hook apparently not supported...
                // Simply call processConfigurationClasses lazily at this point then.
                processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
            }
    
            enhanceConfigurationClasses(beanFactory);
            beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
        }
    

    ConfigurationClassPostProcessor#enhanceConfigurationClasses

    public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
            Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
            for (String beanName : beanFactory.getBeanDefinitionNames()) {
                BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
                if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
                    if (!(beanDef instanceof AbstractBeanDefinition)) {
                        throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
                                beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
                    }
                    else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
                        logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
                                "' since its singleton instance has been created too early. The typical cause " +
                                "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
                                "return type: Consider declaring such methods as 'static'.");
                    }
                    configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
                }
            }
            if (configBeanDefs.isEmpty()) {
                // nothing to enhance -> return immediately
                return;
            }
    
            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);
                try {
                    // Set enhanced subclass of the user-specified bean class
                    Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
                    if (configClass != null) {
                        Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
                        if (configClass != enhancedClass) {
                            if (logger.isDebugEnabled()) {
                                logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
                                        "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
                            }
                            beanDef.setBeanClass(enhancedClass);
                        }
                    }
                }
                catch (Throwable ex) {
                    throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
                }
            }
        }
    

    ConfigurationClassEnhancer#enhance

    public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
            if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
                if (logger.isDebugEnabled()) {
                    logger.debug(String.format("Ignoring request to enhance %s as it has " +
                            "already been enhanced. This usually indicates that more than one " +
                            "ConfigurationClassPostProcessor has been registered (e.g. via " +
                            "<context:annotation-config>). This is harmless, but you may " +
                            "want check your configuration and remove one CCPP if possible",
                            configClass.getName()));
                }
                return configClass;
            }
            Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("Successfully enhanced %s; enhanced class name is: %s",
                        configClass.getName(), enhancedClass.getName()));
            }
            return enhancedClass;
        }
    
        private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(configSuperClass);
            enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
            enhancer.setUseFactory(false);
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
            enhancer.setCallbackFilter(CALLBACK_FILTER);
            enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
            return enhancer;
        }
        
          private Class<?> createClass(Enhancer enhancer) {
            Class<?> subclass = enhancer.createClass();
            // Registering callbacks statically (as opposed to thread-local)
            // is critical for usage in an OSGi environment (SPR-5932)...
            Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
            return subclass;
        }
    

    总之,执行ConfigurationClassPostProcessor.postProcessBeanFactory()方法,在enhanceConfigurationClasses方法对配置类进行增强invokeBeanFactoryPostProcessors(registryProcessors, beanFactory)配置类增强,使用cglib生成代理类


    enhance.png

    BeanFactoryPostProcessor直接子类

    接下来查找BeanFactoryPostProcessor实现类,扩展BeanFactoryPostProcessor是在这些步骤执行的
    invokeBeanFactoryPostProcessors()方法参数值有
    1.priorityOrderedPostProcessors集合中类实现了PriorityOrdered
    2.orderedPostProcessorNames集合中类实现了Ordered
    3.nonOrderedPostProcessorNames没有实现PriorityOrdered和Ordered


    BeanFactoryPostProcessors.png

    BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor类

    BeanFactoryPostProcessor .class

    package org.springframework.beans.factory.config;
    import org.springframework.beans.BeansException;
    @FunctionalInterface
    public interface BeanFactoryPostProcessor {
    
        /**
         * Modify the application context's internal bean factory after its standard
         * initialization. All bean definitions will have been loaded, but no beans
         * will have been instantiated yet. This allows for overriding or adding
         * properties even to eager-initializing beans.
         * @param beanFactory the bean factory used by the application context
         * @throws org.springframework.beans.BeansException in case of errors
         */
        void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    
    }
    
    

    BeanDefinitionRegistryPostProcessor .class

    package org.springframework.beans.factory.support;
    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    
        /**
         * Modify the application context's internal bean definition registry after its
         * standard initialization. All regular bean definitions will have been loaded,
         * but no beans will have been instantiated yet. This allows for adding further
         * bean definitions before the next post-processing phase kicks in.
         * @param registry the bean definition registry used by the application context
         * @throws org.springframework.beans.BeansException in case of errors
         */
        void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
    
    }
    
    

    总结:

    执行bean工厂后置处理器,最终会调用到PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors()方法。在这个方法中会对BeanFactoryPostProcessor 及其子类BeanDefinitionRegistryPostProcessor 的实现类在bean工厂进行查找。首先会对BeanDefinitionRegistryPostProcessor 的子类进行查找,有三种情况,实现BeanDefinitionRegistryPostProcessor和
    PriorityOrdered,实现BeanDefinitionRegistryPostProcessor和Ordered,实现BeanDefinitionRegistryPostProcessor(没有实现Ordered和PriorityOrdered)。在这三种中,符合第一种的是ConfigurationClassPostProcessor类,会执行这个类的postProcessBeanDefinitionRegistry方法,最终调用到processConfigBeanDefinitions方法对配置类full和lite属性设置。设置完成之后对配置类进行解析(@ComponentScan路径扫描,import等的处理),对返回的BeanDefinition进行默认设置,以不同的方式load加载到bean工厂(BeanDefinitionMap)。之后对BeanDefinitionRegistryPostProcessor 的子类的其他两种依次执行。这三种都执行完之后然后执行invokeBeanFactoryPostProcessors方法主要对配置类使用cglib增强。增强之后会对BeanFactoryPostProcessor 的实现类查找,有三种情况,依次会执行自定义实现BeanFactoryPostProcessor 的postProcessBeanFactory方法执行。

    相关文章

      网友评论

        本文标题:invokeBeanFactoryPostProcessors分

        本文链接:https://www.haomeiwen.com/subject/nzxcvctx.html