一文通透spring的初始化

4个月前 (12-11) 0 点赞 0 收藏 0 评论 12 已阅读

简述

今天重点分析ApplicationContext初始化时做的事情,我们都只到spring是个IOC和AOP容器,那再我们new一个ApplicationContext,spring内部都做了什么?怎么实现的IOC和AOP?
比如说下面这段代码

@Configuration
@ComponentScan("com.xxx.xxx")
@EnableAspectJAutoProxy
public class MainApplication {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MainApplication.class);
        IUser user = context.getBean(IUser.class);
        user.sayHi();
    }

}

通过new一个AnnotationConfigApplicationContext我们就得到了这个bean容器,还可以添加切面,那再new的时候都做了什么呐?

BeanFactory

这篇文章的基础是懂得BeanFactory,如果不懂可以做做功课或者翻翻之前的文章~Bean的生命周期和BeanPostProcessor再来,简单总结一下BeanFactory。
BeanFactory能干什么,以最主要的DefaultListableBeanFactory为例

注册bean定义
通过bean定义生产bean并可以随时获取
可以添加bean后置处理器(BeanPostProcessor)来调整bean的创建过程
可以一次性创建所有非懒加载单例bean(preInstantiateSingletons)
等等

ApplicationContext

有了BeanFactory为啥还要有ApplicationContext呐,其实BeanFactory只是一个给图纸(bean定义)生产产品(bean)的工厂,离我们太遥远了,或者说用起来他麻烦了,甚至依赖注入和AOP都不是BeanFactory实现的

如果单纯使用BeanFactory,需要给他添加依赖注入的后置处理器,需要给他加AOP的后置处理器,才能实现这些功能,而使用ApplicationContext这些活它帮干了,它还可以自动扫描包或者读取配置自动生成bean定义注册到BeanFactory当中,还有一些事件的支持和国际化的支持。

所以为什么有ApplicationContext,ApplicationContext就是把一些我们平时开发用到的功能封装好了,我们开发时直接用就可以实现IOC,AOP,事件等功能

它俩的关系就好比工厂和门店,那有了工厂为啥还有有门店呐?单一职责吗,工厂的技术宅就能看懂图纸,你跟他说中国话他听不懂,所以就有了门店,你简单和门店的人说一下你的需求,门店的人帮你画图纸交给工厂生产,整个过程你不需要和工厂接触

后置处理器

后置处理器分为BeanFactoryPostProcessor和BeanPostProcessor

BeanPostProcessor
bean后置处理器,beanFactory可以添加BeanPostProcessor,再生成bean的不同时期执行这些后置处理器,简单来说,通过设置后置处理器,可以再bean的创建过程中植入一些自定义逻辑
BeanFactoryPostProcessor
BeanFactory后置处理器,ApplicationContext可以添加BeanFactoryPostProcessor,再初始化ApplicationContext时会调用这些BeanFactory后置处理器

总结BeanPostProcessor和BeanFactoryPostProcessor都是钩子,前者是存储于beanFactory,再生产bean时候调用,后者存储于ApplicationContext,再初始化ApplicationContext时调用,二者都有很多子类型,以便再不同阶段调用,使代码有很大的扩展性

ApplicationContext

接下来分析ApplicationContext的源码,由于现在都很少用xml这种了,所以我们找了个AnnotationConfigApplicationContext,注解配置的ApplicationContext,也就是现在当然springboot内部用的ApplicationContext,那就开始跟宗AnnotationConfigApplicationContext的构造方法

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}

一共就三局,一个一个跟

this()

调用无参构造方法,首先要调用父类构造方法,父类是GenericApplicationContext,看看他的构造方法

public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
}

这个简单,内部初始化了一个DefaultListableBeanFactory,这个好理解,门店的背后肯定是有工厂的,再来看当前类的无参构造方法

public AnnotationConfigApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

初始化了一个reader,一个scanner,先看看reader
跟踪reader的构造方法会出现这么一条代码

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

这句话很重要,这里的this.registry就是ApplicationContext,在这里扮演一个bean定义注册器的角色,进入这个方法查看~
具体的代码就不贴了,很长可以自己看看,总结就是像这个bean定义注册器注册了很多个后置处理器类型的bean定义,包括BeanFactoryPostProcessor类型和BeanPostProcessor类型,主要有:

配置类解析后置处理器 ConfigurationClassPostProcessor(BeanFactoryPostProcessor)
@Autowired 注解的处理器 AutowiredAnnotation(BeanPostProcessor)
@Required属性的注解处理器 RequiredAnnotation(BeanPostProcessor)
@EventListener解析器 EventListenerMethodProcessor
事件监听器工厂 DefaultEventListenerFactory

注意:上面讨论过两种后置处理器存放的位置,而这时添加的后置处理器并没有存放到相应位置,而是以bean的形式存放在bean容器中

至于为什么在这时机添加后置处理器,应该是这些后置处理器都属于读文件、读类的功能,即reader

register(componentClasses)

这里的componentClasses就是初始化时传入的唯一参数MainApplication.class,register都干了什么呐

public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    this.reader.register(componentClasses);
}

调用刚才初始化的reader的register方法,这里就要介绍reader的主要作用,就是传入一个类,把类转换为bean定义并注册到初始化时传入的bean定义注册器

所以register方法就是把主配置类(MainApplication)解析为bean定义并完成注册

refresh()

这句就是初始化的核心方法了,内部有很多子方法的调用

// Prepare this context for refreshing.
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
    // Allows post-processing of the bean factory in context subclasses.
    postProcessBeanFactory(beanFactory);

    // Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);

    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);

    // Initialize message source for this context.
    initMessageSource();

    // Initialize event multicaster for this context.
    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.
    finishBeanFactoryInitialization(beanFactory);

    // Last step: publish corresponding event.
    finishRefresh();
}

这么多方法,一个一个来吧

1.prepareRefresh

这个先不管,就是做一些准备工作吗,比如记录一下程序开始的时间什么的

2.beanFactory = obtainFreshBeanFactory()

因为refresh方法是再父类中执行的,而beanFactory是在子类初始化的,所以这句话就是父类管子类要beanFactory,也就是刚才GenericApplicationContext无参构造中初始化的DefaultListableBeanFactory

3.prepareBeanFactory

拿到了beanFactory,再给beanFactory做一次准备工作,比如初始化属性什么的

4.postProcessBeanFactory(beanFactory)

Allows post-processing of the bean factory in context subclasses
这句话相当于给子类一个机会做一些操作,比如添加一些后置处理器进来(因为下一步就要执行后置处理器了,再次之前给一个机会再添加一些后置处理),也是为了代码灵活,查看子类并没有再这一步做什么操作

5.invokeBeanFactoryPostProcessors(beanFactory);

重点来了,字面意思执行BeanFactory后置处理器,看一下代码

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

这里相当于把工作交给一个类PostProcessorRegistrationDelegate处理,我们先管他叫后置处理委托器,spring使用这种委托模式来让代码规整,也比较符合单一职责

PostProcessorRegistrationDelegate把后置处理器相关的业务代码从ApplicationContext中抽离出来

那么继续跟到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors这个方法,这个比较重要,得贴下代码

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

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 已执行的后置处理器(bean容器中),为防止重复执行
        Set<String> processedBeans = new HashSet<>();

        // 如果bean工厂是bean定义注册器,比如DefaultListableBeanFactory本身也是可以注册bean定义的注册器
        if (beanFactory instanceof BeanDefinitionRegistry) {
            // bean定义注册器
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 基础型后置处理器集合
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // bean定义注册型后置处理器集合
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 循环后置[参数]后置处理器
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果是bean定义注册型后置处理器,直接执行postProcessBeanDefinitionRegistry,并存入registryProcessors
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                // 如果是基础型后置处理器,直接执行,并存入regularPostProcessors
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // 开始执行[bean容器中]后置处理器
            
            // 当前bean定义注册型后置处理器集合,为了按循序执行
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // 首先,从bean容器中获取带@PriorityOrdered标识的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);
                }
            }
            // 排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 加入registryProcessors
            registryProcessors.addAll(currentRegistryProcessors);
            // 执行当前bean定义注册型后置处理器集合的postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 清空当前bean定义注册型后置处理器集合
            currentRegistryProcessors.clear();

            // 其次, 从bean容器中获取带@Ordered标识的bean定义注册型后置处理器,逻辑和上一步基本一样
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 多了一个!processedBeans.contains判断,避免后置处理器被多次执行
                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();

            // 最后, 执行其他的bean定义注册型后置处理器,知道容器中的所有都被执行过
            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();
            }

            // 执行所有基础型后置处理器的postProcessBeanFactory方法,bean定义注册型后置处理器也是基础型后置处理器的一种,所以也要执行
            // 这里的regularPostProcessors来源于[参数]后置处理器
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // 如果传入的beanFactory不是bean定义注册器,只是简单的执行了[参数]后置处理器的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 开始执行[bean容器中]普通后置处理器,和执行[bean容器中]bean定义注册型后置处理器基本逻辑差不多,都是按循序执行
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // 按@PriorityOrdered, @Ordered, 和无注解,区分优先级
        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);
            }
        }

        // 首先,执行带@PriorityOrdered的.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 其次, 执行带@Ordered的.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // 最终, 执行其他的
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        // 执行了[bean容器中]基础型后置处理器的postProcessBeanFactory方法
        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();
    }

上面的代码还是比较多,但总结起来也不复杂

首先,后置处理器主要有两种:

1).基础型后置处理器(BeanFactoryPostProcessor)
基础型后置处理器,只有一个方法postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory),可以配置bean工厂,比如bean工厂添加一些bean后置处理器

2).bean定义注册型后置处理器(BeanDefinitionRegistryPostProcessor)
bean定义注册型后置处理器,继承BeanFactoryPostProcessor,所以也属于基础型后置处理器的一种,新增一个方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry),增加功能:可以注册一些bean定义

其次,执行后置处理器,那么后置处理器在哪里?从代码里就可以看出
1).【参数】后置处理器
之前ApplicationContext存储了一些BeanFactory后置处理器,可以通过public的addBeanFactoryPostProcessor方法添加,比如springboot启动时就添加了一些后置处理器,这些后置处理器是用第二个参数:getBeanFactoryPostProcessors()传给后置处理委托器的

/** AbstractApplicationContext中 */
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

2).【bean容器中】的后置处理器
ApplicationContext引用了DefaultListableBeanFactory,这个BeanFactory中存放了很多的bean,这些bean有些是后置处理器类型的(比如子类初始化reader时通过AnnotationConfigUtils.registerAnnotationConfigProcessors方法存入的bean),那么只要通过beanFactory调用getBeanNamesForType就可以获取这些后置处理器,比如

// 通过类型获取所有后置处理器的名字
String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
        // 获取到后置处理器
        beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);
    }
}

存在两个地方的后置处理器,分别通过BeanFactory和getBeanFactoryPostProcessors()传给后置处理委托器,那么下一步后置处理委托器就是执行这两种来源的后置处理器

执行过程就是上面代码,比较有意思,考虑到传入的参数DefaultListableBeanFactory本身就是BeanDefinitionRegistry所以执行逻辑如下

执行[参数]后置处理器中的bean定义注册型后置处理器postProcessBeanDefinitionRegistry方法
查找bean容器,执行[bean容器中]后置处理器中的bean定义注册型后置处理器postProcessBeanDefinitionRegistry方法,这个过程会按@PriorityOrdered>@Ordered>Other 顺序依次分批执行,执行完一批会重新去bean容器获取一次,直到获取不到为止,这样非常巧妙,如果某个bean定义注册型后置处理器有注册了一个该类型后置处理器,该后置处理器就会在后续的查找中被找出并执行,即可以用后置处理器添加后置处理器,有点传销的意思

执行上两步bean定义注册型后置处理器的postProcessBeanFactory方法
执行[参数]后置处理器中基础型后置处理器的postProcessBeanFactory方法
查找bean容器,执行执行[bean容器中]后置处理器中的基础型后置处理器的postProcessBeanFactory方法,依然是按@PriorityOrdered>@Ordered>Other批次进行执行,但不会在这期间再次重新查找bean容器

总结:这一步完成了对两种来源的两种类型的beanFactory后置处理器的调用,期间注册型后置处理器注册的新后置处理器也会被执行

6.registerBeanPostProcessors(beanFactory);

beanFactory后置处理器的添加和调用都结束了,下一步就要开始弄bean后置处理了,前面讲过bean后置处理器是存在beanFactory中的,所以参数还是传了个beanFactory

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

同样还是交给了后置处理委托器去处理,上面reader初始化的时候往bean容器里加了一些beanFactory后置处理同时也有bean后置处理器,以bean的形式存储,那总得有人把这些后置处理器给摘出来放到beanFactory的bean后置处理列表里才能再创建时被调用,因为beanFactory的后置处理器存储地点如下

private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

但是上面reader却把后置处理器放到了bean容器中,那肯定执行不了啊,所以这一步就是把beanFactory中的bean后置处理器类型的bean定义生产出来放入beanPostProcessors中,这些bean定义除了reader添加的几个还有大部分是上一步beanFactory后置处理器执行时加入到bean容器的

总结:这一步完成把以bean形式存储在beanFactory中的后置处理器摘出来放到beanFactory中专门存放后置处理器的地方,以便后续创建bean时使用

7.initMessageSource

国际化的一些处理,以后研究

8.initApplicationEventMulticaster

事件处理,以后研究

9.onRefresh

也是一个钩子,默认什么都不做,子类可以覆盖去做点事

10.registerListeners

事件的处理,以后研究

11.finishBeanFactoryInitialization(beanFactory)

这一步就很重要了,看注释Instantiate all remaining (non-lazy-init) singletons,实例化所有非懒加载的bean,也就是调用beanFactory的preInstantiateSingletons方法,创建所有单例bean(非懒加载的bean)

12.finishRefresh

结束后的一些操作,比如发布初始化结束事件等

总结

到此,refresh方法分析完了,抛去一些事件国际化相关的辅助代码,主要结合之前的流程总结如下

配置主方法注入到bean容器
添加一些beanFactory后置处理器和bean后置处理器,还有一些其它的bean至bean定义注册器
执行beanFactory后置处理器,分BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor两种,通过BeanFactoryPostProcessor可以配置bean工厂,通过BeanDefinitionRegistryPostProcessor可以注册一些bean定义也配置bean工厂,其间BeanDefinitionRegistryPostProcessor可以注册新的后置处理器,也会再后续执行
提取bean容器中bean后置处理器类型的bean,添加到bean工厂的bean后置处理器列表中
初始化所有单例非懒加载bean

到此spring启动时所执行重点方法就分析完了,其实按总结来看,就那么几个重点步骤,但是所谓的IOC和AOP到底如何实现的呐,并没有相关代码啊?

其实,这些功能都是通过后置处理器来实现的,也就是spring定义了一套后置处理器执行的规则,并把重点的工作都交给了内置的后置处理器来实现

IOC

spring是一个IOC容器,能把我们写的@Service,@Controller,@Component的类的bean定义注册,并生成bean加入容器,但刚刚我们看了new ApplicationContext的流程代码,发现用户写的类唯一被注册成bean定义就只有MainApplication.class

那么其他的bean(@Service,@Controller,@Component修饰的)是合适注册为bean定义的?

其实这部分工作就是后置处理器ConfigurationClassPostProcessor完成的,就是上文read构造时registerAnnotationConfigProcessors方法注册的后置处理器

ConfigurationClassPostProcessor翻译过来就是配置类后置处理器,就是专门处理配置类的,它继承了BeanDefinitionRegistryPostProcessor,因此拥有注册bean定义的能力

ConfigurationClassPostProcessor

那么重点看一下它的postProcessBeanDefinitionRegistry方法

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    // 省略
    processConfigBeanDefinitions(registry);
 }

进入processConfigBeanDefinitions,只捡主要代码贴,可自行对照

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    // 创建一个解析器,解析@Configuration注解的类
    ConfigurationClassParser parser = new ConfigurationClassParser(
                this.metadataReaderFactory, this.problemReporter, this.environment,
                this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    // 开始解析,这个candidates就是我们传入的MainApplication
    parser.parse(candidates);
    // 获取解析到的类
    Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
    // 初始化一个reader
    this.reader = new ConfigurationClassBeanDefinitionReader(
                        registry, this.sourceExtractor, this.resourceLoader, this.environment,
                        this.importBeanNameGenerator, parser.getImportRegistry());
    // 把上面解析到的类转化为bean定义并注册到bean定义注册器(registry)
    this.reader.loadBeanDefinitions(configClasses);
}

使用ConfigurationClassParser.parse进行配置类解析,而这个方法就包含了解析@ComponentScan@Import等注解

@ComponentScan就是我们制定的扫描包路径,会扫描路径下@Component注解的类(包括子注解@Configuration@Service等),注册成bean定义,同时会继续递归parse解析扫描到的ConfigurationClass(一般只带有@Configuration注解),直到把我们指定的所有bean加入bean容器

这里的源码分析可查看文章:spring如何扫描解析bean(注册bean的多种方式)

依赖注入

依赖注入是通过BeanPostProcessor实现的,即AutowiredAnnotationBeanPostProcessor,依然是上文read构造时registerAnnotationConfigProcessors方法注册的后置处理器,它修改了bean生命周期中填充属性的过程:

查询带有@Autowired属性
通过属性的type在bean容器中使用getBeanByType方式查找要注入的bean
反射给属性赋值

细节可以参照文章Spring之@Autowired依赖注入探究

AOP

ConfigurationClassParser.parse的时候还会扫描@Import注解,如果@Import的类继承了ImportBeanDefinitionRegistrar就可以自定义注册一些bean(参照:spring如何扫描解析bean(注册bean的多种方式))。
AOP就是使用这种@Import+ImportBeanDefinitionRegistrar的方式完成AOP功能可配置的---注解@EnableAspectJAutoProxy,有则可以AOP,没有则不能AOP

@EnableAspectJAutoProxy

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    // 省略
}

其中引入了AspectJAutoProxyRegistrar,而AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,那么这个注解通过这种方式注册了什么bean呐?
答案就是bean后置处理器AnnotationAwareAspectJAutoProxyCreator,用来再bean创建过程中实现动态代理。

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
        BeanDefinitionRegistry registry, @Nullable Object source) {
    // 注册AnnotationAwareAspectJAutoProxyCreator
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator继而继承BeanPostProcessor,创建代理的代码就写在AbstractAutoProxyCreator.wrapIfNecessary方法里,对其刚兴趣可以参考我之前的AOP系列文章

最后

这篇文章是根据之前的一篇文章改的,主要是因为之前写的有些不对,而且需要这里的知识时又发现很多地方已经忘了,所以这次要画一张大图,把今天总结的逻辑都包含在图中,下次再看,一目了然~

ApplicationContext


一文通透spring的初始化

本文收录在
Array
0评论

登录

忘记密码 ?

切换登录

注册