Spring IoC源码分析(注解版) -- 中

上一篇文章Spring IoC源码分析(注解版) -- 上 分析了Spring IoC容器中关于BeanDefinition的registy过程。我们接着来分析剩下的内容。

加载BeanDefinition

上一篇我们分析完了AnnotationConfigApplicationContext类中的register方法,现在来分析refresh方法。refresh其实是在AbstractApplicationContext类中实现的。AbstractApplicationContext实现了BeanDefinitionRegistry以及BeanFactory的大部分功能,所以其子类如AnnotationConfigApplicationContext或ClassPathXmlApplicationContext只需要实现部分相关功能(如加载resource)即可。

我们来看refresh方法的代码:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
            // 设置一些属性值,如开始日期等,不是重点
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // 获取beanFactory,对于AnnotationConfigApplicationContext而言,其实在其父类GenericApplicationContext的构造函数中就已经创建好了,beanFactory是DefaultListableBeanFactory类的一个实例。
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            
            // 配置一些必要的对象,如ClassLoader,也不是重点。
            prepareBeanFactory(beanFactory);

            try {
                // BeanFactory后置处理器回调函数,让子类有机会在创建beanFactory之后,有机会对beanFactory做额外处理。模板方法模式的使用。
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // 调用BeanFactoryPostProcessor的postProcessBeanFactory方法。
                // Spring提供了BeanFactoryPostProcessor接口,用于对BeanFactory进行扩展。如果一个Bean实现了BeanFactoryPostProcessor接口的话,在这里会调用其接口方法。
                // 这个方法和上一个方法的区别在于,上一个方法是调用ApplicationContext子类的postProcessBeanFactory方法,而这个方法是调用所有BeanFactoryPostProcessor实例的postProcessBeanFactory方法。这个方法做了很多事情,是我们要重点分析的对象。
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 只是注册BeanPostProcessor,还没调用后置处理器相关的方法。如果Bean实现了BeanPostProcessor接口的话,在这里注册其后置处理器。
                // BeanPostProcessor也是Spring提供的另一个有用接口,所有的BeanPostProcessor会被添加到Spring容器列表中。在应用Bean被实例化前后,Spring会一次调用BeanPostProcessor列表中的接口方法。后边会有具体分析。
                // 所有实现了BeanFactoryPostProcessor和BeanPostProcessor接口的Bean,理论上是提供给Spring使用的,我们叫他功能性Bean。而其它Bean,如UserService,叫应用型Bean。
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // 国际化的东西,不是重点。
                initMessageSource();

                // Initialize event multicaster for this context.
                // 我们现在不讨论事件机制,主要关注Bean的加载和创建过程,所以跳过。
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // 好吧,又来一个回调方法,模板方法模式哟。
                onRefresh();

                // Check for listener beans and register them.
                // 不讨论事件机制,跳过。
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // 这又是一个重点方法。这个方法会实例化所有非lazy-init的singleton bean,并执行与Spring Bean生命周期相关的方法。如init-method,*aware接口方法等。
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // 与事件有关,跳过
                finishRefresh();
            }
        }
}

refresh方法中执行了许多方法,但其实我们如果想了解Bean加载及创建,只要关注3个即可,他们是。

invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);

现在来一一分析分析,先看invokeBeanFactoryPostProcessors。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 委托给PostProcessorRegistrationDelegate执行,调用以下方法
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    // 省略其它
        }
    }

再来看PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        if (beanFactory instanceof BeanDefinitionRegistry) {
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
            
            // 先处理BeanDefinitionRegistryPostProcessor,并调用其postProcessBeanDefinitionRegistry方法。
            // BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的一个子接口,它允许注册更多的BeanDefinition。我们之前讲过,前面的register方法中,只注册了配置类(添加了@Configuration的类),其它类的BeabnDifination还没有被注册进来
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 这里会得到一个ConfigurationClassPostProcessor类,这个类的作用很明显,就是要继续注册配置类中要求注册的BeanDefination,如在配置类上添加了@ComponentScan注解,那么会进行包扫描,指定包下的所有添加了@Component,@Service等注解的类全部注册进来。
                // 那么这个类是什么时候注册的呢,我们稍后会讲。
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 在这里开始调用BeanDefinitionRegistryPostProcessor的后置处理器postProcessBeanDefinitionRegistry方法。
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // 省略大量重复代码,主要处理各种优先级的BeanFactoryPostProcessor对象。可以为BeanFactoryPostProcessor设置优先级,优先级高的对象会先被调用。

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

    
        // 对所有的postProcessor进行分类,高优先级的和正常优先级的分别放在不同的列表中,高优先级的先调用其postProcessBeanFactory方法。      
        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);
            }
        }
    

        // 此处省略重复调用代码,就是对高优先级的BeanFactoryPostProcessor先执行invokeBeanFactoryPostProcessors方法,然后是低优先级,再之后是无优先级的
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            // 这里这行代码,它调用了beanFactory.getBean方法。我们知道只要调用了getBean方法,如果Bean没有被加载,Spring就会创建该Bean,并对其进行相关属性复制。所以对于实现了BeanFactoryPostProcessor的Bean,在这里就已经进行实例化了。因为它要拿到当前对象,才能执行其接口方法。
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 开始进行回调。
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);     
        beanFactory.clearMetadataCache();
    }

我们来介绍一下BeanFactoryPostProcessor接口,它叫BeanFactory后置处理器。如果你的类实现了这个接口,那么在BeanFactory创建完成之后,Spring会调用这个类的postProcessBeanFactory方法。这个类为用户提供了扩展BeanFactory的机会。

接下来要说的东西很多,我们首先要讲ConfigurationClassPostProcessor是怎么注册进来的,然后再分析ConfigurationClassPostProcessor的processConfigBeanDefinitions代码,最后分析invokeBeanFactoryPostProcessors方法。

先来看ConfigurationClassPostProcessor的注册过程。回到最初AnnotationConfigApplicationContext的构造函数中。

public AnnotationConfigApplicationContext() {
        // 创建了一个AnnotatedBeanDefinitionReader对象,ConfigurationClassPostProcessor这个类就是在这里注入的。
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

我们继续往下看AnnotatedBeanDefinitionReader的构造函数。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        this.registry = registry;
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        // 注册注解配置类的处理器。
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

进入AnnotationConfigUtils.registerAnnotationConfigProcessors方法。

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        // 调用了registerAnnotationConfigProcessors方法
        registerAnnotationConfigProcessors(registry, null);
    }

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);    

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            // 看见没有,在这里注册了ConfigurationClassPostProcessor类。
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 主要是调用了registerPostProcessor来进行注册的。
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 同时也注册了另一个重要类AutowiredAnnotationBeanPostProcessor
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
        // 其它代码就不看了。省略...

        return beanDefs;
    }

简单看一下registerPostProcessor,就是调用registerBeanDefinition注册一个BeanDefination。不往下看了,前面register里讲到过。

private static BeanDefinitionHolder registerPostProcessor(
            BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

        definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(beanName, definition);
        return new BeanDefinitionHolder(definition, beanName);
    }

现在ConfigurationClassPostProcessor的注册过程弄明白了。我们接着看下一段代码分析,调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法。ConfigurationClassPostProcessor这个类是Spring帮我们注册进来,其作用是用于注册用户自定义的类。看源代码:

// 接着PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors的代码分析,会调用以下方法
private static void invokeBeanDefinitionRegistryPostProcessors(
            Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

        for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
            // 这里的postProcessor就是ConfigurationClassPostProcessor
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
    }

进入ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法。

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 开始注册Config类中定义的BeanDefinition
        processConfigBeanDefinitions(registry);
    }
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        String[] candidateNames = registry.getBeanDefinitionNames();

        // 将配置类放在configCandidates列表中。代码省略...

        // 创建配置类的分析器,对配置类进行分析。配置类就是我们添加了@Configuration注解的类,可以有多个的。我写的demo中只有一个,叫SpringConfig。
        ConfigurationClassParser parser = new ConfigurationClassParser(
                this.metadataReaderFactory, this.problemReporter, this.environment,
                this.resourceLoader, this.componentScanBeanNameGenerator, registry);

        Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
        do {
            // 开始分析配置类
            parser.parse(candidates);
            parser.validate();

            // 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());
            }
            // 加载BeanDefinition
            this.reader.loadBeanDefinitions(configClasses);
        }
        while (!candidates.isEmpty());
    }

上面方法中,我们需要分析两个方法parser.parse(candidates)和this.reader.loadBeanDefinitions(configClasses)。先来看第一个方法:

public void parse(Set<BeanDefinitionHolder> configCandidates) {
        for (BeanDefinitionHolder holder : configCandidates) {
            // 调用链往下看
            parse(bd.getBeanClassName(), holder.getBeanName());
        }
        this.deferredImportSelectorHandler.process();
    }

protected final void parse(Class<?> clazz, String beanName) throws IOException {
        // 继续往下看
        processConfigurationClass(new ConfigurationClass(clazz, beanName));
    }

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {   

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

通过一些列调用,最终调用到了doProcessConfigurationClass方法。

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
            throws IOException {
    
        // 这两个方法简单过,就是处理配置类里边的内部类和@PropertySource注解
        processMemberClasses(configClass, sourceClass);
        processPropertySource(propertySource);      

        // 处理 @ComponentScan 注解类,重点,先获取加了@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
                // 开始扫描指定package下的所有Bean,那些加了@Component,@Service,@Repository等注解的类,都会加进来。
                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(bdCand, this.metadataReaderFactory)) {
                        // 这个方法我们就不分析了,递归哈
                        parse(bdCand.getBeanClassName(), holder.getBeanName());
                    }
                }
            }
        }

        // Process any @Import annotations
        processImports(configClass, sourceClass, getImports(sourceClass), true);        

        // Process individual @Bean methods
        // 将所有都添加了@Bean注解的方法添加到configClass中,这里没有注册,仅仅只是添加。后边有一个叫reader.loadBeanDefinitions的方法来处理它。
        Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
        for (MethodMetadata methodMetadata : beanMethods) {
            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
        }

        // Process default methods on interfaces
        processInterfaces(configClass, sourceClass);        

        // No superclass -> processing is complete
        return null;
    }

上面的方法中,我们来看componentScanParser.parse方法,看是怎样扫描包并且注册BeanDefinition的。

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
        // 创建scanner
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
                componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
        Set<String> basePackages = new LinkedHashSet<>();
        // 添加所有的package,代码省略...
        // 开始扫描
        return scanner.doScan(StringUtils.toStringArray(basePackages));
    }

我们接下来看scanner.doScan

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
        for (String basePackage : basePackages) {
            // 找出当前包下面的所有符合条件的类,这个方法我们就不分析了。
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {
                // 处理一些其他情况,也不说了...
                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);
                    // 最后注册BeanDefinition,这样就将包下的所有BeanDefintion都注册完成了
                    registerBeanDefinition(definitionHolder, this.registry);
                }
            }
        }
        return beanDefinitions;
    }

到这里为止,我们配置类的分析就结束了,将所有的包下的BeanDefinition都注册完成了。讲了这么多,我们还记得是从哪个方法进来的吗?是从这个ConfigurationClassPostProcessor的processConfigBeanDefinitions方法进来的,再回到这个方法。

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        String[] candidateNames = registry.getBeanDefinitionNames();
        
        ConfigurationClassParser parser = new ConfigurationClassParser(
                this.metadataReaderFactory, this.problemReporter, this.environment,
                this.resourceLoader, this.componentScanBeanNameGenerator, registry);

        Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
        do {
            // 刚才是在这里一下向下分析的。
            parser.parse(candidates);
            parser.validate();

            // 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());
            }
            // 加载BeanDefinition
            this.reader.loadBeanDefinitions(configClasses);
        }
        while (!candidates.isEmpty());
    }

现在我们来分析reader.loadBeanDefinitions方法。

private void loadBeanDefinitionsForConfigurationClass(
            ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
        // 处理Imported的配置类
        if (configClass.isImported()) {
            registerBeanDefinitionForImportedConfigurationClass(configClass);
        }
        for (BeanMethod beanMethod : configClass.getBeanMethods()) {
            // 注册所有的@Bean方法上的类,重点看一下这个方法
            loadBeanDefinitionsForBeanMethod(beanMethod);
        }

        // 处理其它注解,这里就不分析了。
        loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
                 loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
    }

看看loadBeanDefinitionsForBeanMethod这个方法

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
        ConfigurationClass configClass = beanMethod.getConfigurationClass();        
        // 一些别名处理的代码都省略了...

        //  创建BeanDefinition
        ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);

        // 处理initMethod和destroyMethod
        String initMethodName = bean.getString("initMethod");
        if (StringUtils.hasText(initMethodName)) {
            beanDef.setInitMethodName(initMethodName);
        }

        String destroyMethodName = bean.getString("destroyMethod");
        beanDef.setDestroyMethodName(destroyMethodName);        

        // Replace the original bean definition with the target one, if necessary
        BeanDefinition beanDefToRegister = beanDef;
        // 最后注册这个BeanDefinition
        this.registry.registerBeanDefinition(beanName, beanDefToRegister);
    }

现在,所有加了@Bean注解的方法定义的BeanDefinition也都被注册了。

总结

讲到这里,感觉说了好多,还记得从哪里进来的吗,对,是从invokeBeanDefinitionRegistryPostProcessors这个方法。今天讲的还挺多的,在继续之前,我们先回顾一下今天讲的知识。

AnnotationConfigApplicationContext构造函数中会创建一个AnnotatedBeanDefinitionReader实例,用于读取基于注解的BeanDefinition。在这个Reader创建过程中,会注册ConfigurationClassPostProcessor类,ConfigurationClassPostProcessor负责加载配置类中的BeanDefinition。

之后调用register和refresh方法。

register方法中注册配置类的BeanDefinition。

refresh方法中包含一系列方法,其中也包含一些扩展方法,是基于模板方法模式的,如postProcessBeanFactory,但我们主要关注的是下边3个。

invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);

invokeBeanFactoryPostProcessors负责调用BeanFactory的后置处理方法,所有实现了BeanFactoryPostProcessor接口的Bean,在这个阶段都会调用其postProcessBeanFactory。

Spring提供了一个重要的类ConfigurationClassPostProcessor,在这个阶段被调用,目的是分析并扫描配置类要求注入的类,并为这些类注册BeanDefinition。

BeanFactoryPostProcessor是Spring提供的用于扩展BeanFactory的接口。用户可以自定义一些类并实现这个接口,这样在IoC容器初始化的过程中,这些BeanFactoryPostProcessor对象的接口方法会被执行。


所有文章在Github上同步,你也可以访问我的个人博客点击查看

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容