8_invokeBeanFactoryPostProcessors

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

进入到对应的方法中

public static void invokeBeanFactoryPostProcessors(

                            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

 

                   // Invoke BeanDefinitionRegistryPostProcessors first, if any.

                   Set<String> processedBeans = new HashSet<String>();

        //首先判断当前的beanFactory是否实现了registry接口

                   if (beanFactory instanceof BeanDefinitionRegistry) {

                            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

                            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();

                            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();

           //invoke传入的postProcessors

                            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<BeanDefinitionRegistryPostProcessor>();

 

                            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.

           //获取所有的BeanDefinitionRegistryPostProcessor类型的bean

                            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);

                                     }

                            }

         //先是实现了PriorityOrdered接口的processors

                            sortPostProcessors(currentRegistryProcessors, beanFactory);

                            registryProcessors.addAll(currentRegistryProcessors);

                            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

                            currentRegistryProcessors.clear();

 

                            // 实现了Ordered.之所以又重新获取了一遍,有可能在经过上面一个

           //postProcessors又增加了新的BeanDefinitionRegistryPostProcessor

                            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();

 

                            // invoke剩余的。

                            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<BeanFactoryPostProcessor>();

                   List<String> orderedPostProcessorNames = new ArrayList<String>();

                   List<String> nonOrderedPostProcessorNames = new ArrayList<String>();

                   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<BeanFactoryPostProcessor>();

                   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<BeanFactoryPostProcessor>();

                   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, Ordered接口,以及都没实现依次进行调用对应的

postProcessor.postProcessBeanDefinitionRegistry(registry);方法

在后面依次获取到BeanFactoryPostProcessor类的bean.再根据是否实现了PriorityOrdered, Ordered进行依次调用

postProcessor.postProcessBeanFactory(beanFactory);

从以上我们可以总结出:如果想在bean创建之前添加注册bean的时候可以通过实现

BeanFactoryPostProcessor或者BeanDefinitionRegistryPostProcessor。通过复写其中的方法,进行注册相关的bean的注册。

下面我们来分析一下通过配置类进行解析组件的加载过程(区分之前在xml配置context:component-scan标签)。还记得上篇文章我们讲过通过AnnotationConfigApplicationContext创建上下文的时候会为我们注册一个ConfigurationClassPostProcessor处理器吗。我们首先看一下这个类。

从图中可以看出他实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered接口。

也就意味着。在invokeBeanFactory的时候会调用其postProcessorBeanDefinitionRegistry方法

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {

        //根据当前得beanFactory生成一个hashCode.并把他保存在正在注册的set中

        //防止重复注册,方法被调用多次

                   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);

         }

下面进入processConfigBeanDefinitions

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {

                   List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();

                    //获取当前注册的所有的bean.

String[] candidateNames = registry.getBeanDefinitionNames();

//遍历当前注册的所有的bean,判断当前的bean是否可以作为配置类

                   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

                   Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {

                            @Override

                            public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {

                                     int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());

                                     int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());

                                     return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;

                            }

                   });

 

                   // 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 && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {

                                     BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);

                                     this.componentScanBeanNameGenerator = generator;

                                     this.importBeanNameGenerator = generator;

                            }

                   }

 

                   // 创建一个配置类解析类

                   ConfigurationClassParser parser = new ConfigurationClassParser(

                                     this.metadataReaderFactory, this.problemReporter, this.environment,

                                     this.resourceLoader, this.componentScanBeanNameGenerator, registry);

 

                   Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);

                   Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());

        //不断的循环,对当前的配置类进行不断地解析

                   do {

                            parser.parse(candidates);

                            parser.validate();

 

                            Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(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());

                            }

           //从配置类加载bean的定义

                            this.reader.loadBeanDefinitions(configClasses);

                            alreadyParsed.addAll(configClasses);

 

                            candidates.clear();

                            if (registry.getBeanDefinitionCount() > candidateNames.length) {

                                     String[] newCandidateNames = registry.getBeanDefinitionNames();

                                     Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));

                                     Set<String> alreadyParsedClasses = new HashSet<String>();

                                     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) {

                            if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {

                                     sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());

                            }

                   }

 

                   if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {

                            ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();

                   }

         }

下面我们先来看下,怎么判断当前类是配置类的

进入ConfigurationClassUtils的checkConfigurationClassCandidate

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;

                            }

                   }

        //判断当前类是否有@ Configuration注解

                   if (isFullConfigurationCandidate(metadata)) {

                            beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);

                   }

        //判断该类是否有@Component @ComponentScan @Import @ImportResource注解

       //以及方法上是否有@Bean注解

                   else if (isLiteConfigurationCandidate(metadata)) {

                            beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);

                   }

                   else {

                            return false;

                   }

 

                   // It's a full or lite configuration candidate... Let's determine the order value, if any.

                   Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());

                   if (orderAttributes != null) {

                            beanDef.setAttribute(ORDER_ATTRIBUTE, orderAttributes.get(AnnotationUtils.VALUE));

                   }

                   return true;

         }

从上面的的方法可以看出如果一个类包含@Component @ComponentScan @Import @ImportResource,@Configuration 以及方法中包含@Bean注解都会作为候选的配置类。重新进行相关解析。

下面我们看一下对应的解析方法,进入ConfigurationClassParser的processConfigurationClass

方法

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {

            //根据condition判断当前的额类是否需要加载。不需要直接返回  

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);

                                     for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext();) {

                                               if (configClass.equals(it.next())) {

                                                        it.remove();

                                               }

                                     }

                            }

                   }

 

                   //将当前的类封装,继续进行处理

                   SourceClass sourceClass = asSourceClass(configClass);

                   do {

                            sourceClass = doProcessConfigurationClass(configClass, sourceClass);

                   }

                   while (sourceClass != null);

 

                   this.configurationClasses.put(configClass, configClass);

         }

进入doProcessConfigurationClass

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)

                            throws IOException {

 

                   // Recursively process any member (nested) classes first

                   processMemberClasses(configClass, sourceClass);

 

                   //解析 @PropertySource 注解

                   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");

                            }

                   }

 

                   // 解析@ComponentScan注解

                   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) {

                                               if (ConfigurationClassUtils.checkConfigurationClassCandidate(

                                                                 holder.getBeanDefinition(), this.metadataReaderFactory)) {

                                                        parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());

                                               }

                                     }

                            }

                   }

 

                   //解析 @Import 注解

                   processImports(configClass, sourceClass, getImports(sourceClass), true);

 

                   // Process any @ImportResource annotations

                   if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {

                            AnnotationAttributes importResource =

                                               AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);

                            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);

                            }

                   }

 

                   // 解析@Bean 方法注解

                   Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);

                   for (MethodMetadata methodMetadata : beanMethods) {

                            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));

                   }

 

                   // Process default methods on interfaces

                   processInterfaces(configClass, sourceClass);

 

                   if (sourceClass.getMetadata().hasSuperClass()) {

                            String superclass = sourceClass.getMetadata().getSuperClassName();

                            if (!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;

         }

//针对Import标签

会分为三种

         1:import的是一个普通类,将其直接作为ConfigurationClass继续处理。也就是调用

                   processConfigurationClass(candidate.asConfigClass(configClass));

         2:import的是一个ImportSelector接口的类,会通过调用selectImports方法获取到一堆子需要增加的一组类的全限定名数组。

         然后继续递归调用doImports方法。这样就可以直接找到最后的普通类或者配置类。

3:如果是一个实现了ImportBeanDefinitionRegistrar接口的类。把其放入到

  importBeanDefinitionRegistrars  map中,在后续继续处理。

通过这一些列的解析并没有把当前的数据全部解析出来。对于方法的bean都是放到了配置类对应的属性中比如beanMethods中。

下面还会继续通过

this.reader.loadBeanDefinitions(configClasses);

进行相关数据的解析与bean的加载。

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);

                   }

        //注册beanMethod

                   for (BeanMethod beanMethod : configClass.getBeanMethods()) {

                            loadBeanDefinitionsForBeanMethod(beanMethod);

                   }

        //注册ImportSource

                   loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());

                   //注册实现了ImportBeanDefinitionRegistr的接口

loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

         }

需要特别注意的是前面的parse方法解析只是将有可能存在的循环的进行递归解析

比如Import的类中可能含有@Bean,或者@ComponentScan等可以引入bean的注解。所以采用递归调用。

而像@Bean修饰的在经过loadBeanDefinitions进行解析注册的只是不可能在引入bean的类。比如你可以实现一个ImportBeanDefinitionRegistrar,在该类注册一个bean.该bean含有ComponentScan注解或者@Import注解。你会发现这些注解全部失效了。也就是不能再进行二次引入了。这就是为什么会出现一个解析,一个加载bean的定义,示例代码如下public

class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {

 

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

             boolean blue = registry.containsBeanDefinition("com.test.bean.color.Blue");

                        if(!blue){

                RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Blue.class);

                registry.registerBeanDefinition("blue",rootBeanDefinition);

            }

    }

}

 

@Import(value ={Red.class})

public class Blue {

}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值