Spring的启动流程探索

3551 篇文章 121 订阅

run方法

我们都知道springboot工程是通过run方法启动的,如图:

Banner printedBanner = this.printBanner(environment);就是我们熟悉的springboot工程启动的时候在控制台打印的log,我们也可以通过配置改变log的打印。

一,context = this.createApplicationContext()

image.png

我们先介绍context = this.createApplicationContext();方法,这个方法顾名思义是创建应用上下文的,应用上下文我们都知道是用来扫描Bean的,并且种类很多。那我们spring使用了应用上下文那些去获取Bean吗,打断点进入这个方法

image.png

可以看到在这里new AnnotatedBeanDefinitionReader(this);new了一个用于读取带有注解的Bean对应的BeanDefinition,还new了一个new ClassPathBeanDefinitionScanner(this);用于从路径读取Bean的BeanDefinition。

在new AnnotatedBeanDefinitionReader的时候会去调用它的构造方法,在它的构造方法里面会去将它的AnnotatedBeanDefinitionReader的BeanDefinition加入到DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap,这两个就是后面创建Bean必须的东西,所有Bean的注册底层都是使用的BeanDefinition。如图:

图片1.png

添加到DefaultListableBeanFactory这个类的beanDefinitionNamesbeanDefinitionMap

image.png

图片3.png

总的来说具体来说,createApplicationContext()方法会根据指定的配置文件(通常是XML文件)或Java配置类来创建和初始化ApplicationContext。配置文件中包含了应用程序中各种bean的定义和配置信息,Spring会根据这些信息创建出对应的bean实例,并将它们注入到相应的对象中,从而完成整个应用程序的初始化。

二,this.prepareContext()

image.png

1context.setEnvironment(environment);这一步不用多说,就是将环境变量set到context中,设置上下文的环境。

2this.postProcessApplicationContext(context);这步操作主要是对ApplicationContext进行后置处理。那么做了哪些后置处理呢?我们点进去看下:

image.png

主要做了3部分:1.设置ApplicationContext的beanNameGenerator。2.设置ApplicationContext的ResourceLoader和ClassLoader。3.设置ApplicationContext类型转换service

3this.applyInitializers(context); 这个方法就是获取之前获取到的所有initializer类型的类,并进行初始化。

4listeners.contextPrepared(context);这个方法是通知监听器 context 准备完成;

5if (this.logStartupInfo) { this.logStartupInfo(context.getParent() == null); this.logStartupProfileInfo(context); }这个代码就是打印日志,这里不做过多描述。

6ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();这个方法就是获取DefaultListableBeanFactory的实例。

7beanFactory.registerSingleton(“springApplicationArguments”, applicationArguments);这步操作是注册了一个单例,单例名为“springApplicationArguments”,值为applicationArguments。

8if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}这步是判断printedBanner是否为空,如果不为空,就注册一个名为springBootBanner,值为printedBanner的单例

9if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}这个方法主要是配置bean如果重名,是否允许后一个bean覆盖前一个bean,默认是false,此时如果有同名的bean,注册到容器中,那么就会报异常。

10Set<Object> sources = this.getAllSources();获取sources列表,这里可以获取到启动类的class

image.png

11this.load(context, sources.toArray(new Object[0]));这个方法就是加载启动类,将启动类注入到容器里面。

图片4.png

可以看到beanDefinitionNamesbeanDefinitionMap里面已经有6个了。都是主配置类。

image.png

12listeners.contextLoaded(context);这个方法我们点进去看下:

image.png

image.png

这里就是将在SpringApplciationInitialize()方法中注册的listener中属于ApplicationContextAware类型的bean都执行方法setApplicationContext,同时将这些Listener都加入到ApplicationContext中,并发布事件ApplicationPreparedEvent

三,this.refreshContext(context)

这个就是刷新容器的方法

image.png

1.this.prepareRefresh(),进入这个方法。

image.png

this.startupDate = System.currentTimeMillis();设置容器启动的时间

this.closed.set(false);容器的关闭标志位

this.active.set(true);将容器状态设置为有效,

this.initPropertySources();留给子类覆盖,初始化属性资源

this.getEnvironment().validateRequiredProperties();创建并获取环境对象,验证需要的属性文件是否都已经放入环境中。

最后去判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到集合中。

三,ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory()

这个用于获取设置容器序列化id和BeanFactory

image.png

1.this.refreshBeanFactory();,点进去看

image.png

首先使用了CAS去判断容器是否已经启动,没有启动就给beanFactory设置一个序列化id。

image.png

设置的序列化id就是你的服务名称。

2.this.getBeanFactory();,点进去看,调用了getBeanFactory方法获取了beanFactory,而beanFactory是在这个通用上下文构造方法里面就创建了的DefaultListableBeanFactory

image.png

四,this.prepareBeanFactory(beanFactory)

点进去看

image.png

这个方法就是给工厂设置必须的工具,比如el表达式解析器,资源解析器,后置处理器等。

五,this.postProcessBeanFactory(beanFactory)

这个是留给子类的模板方法,允许子类对工厂执行一些处理,给Bean设置属性,单例Bean修改为多例,或者移除BeanDefinition从而避免某个Bean在spring容器中的创建。例如:

image.png

又或者用它的子类接口BeanDefinitionRegistryPostProcessor,如图

image.png

最后别忘记把这两个配置类注入到容器当中

image.png

六,this.invokeBeanFactoryPostProcessors(beanFactory)

这个就是去调用Bean工厂主处理器,

图片5.png

 
java复制代码public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 将已经执行过的BeanFactoryPostProcessor存储在processedBeans,防止重复执行
        Set<String> processedBeans = new HashSet<>();

        // 此处条件成立,BeanFactory类型为DefaultListableBeanFactory,而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 用来存放BeanFactoryPostProcessor对象
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 用来存放BeanDefinitionRegistryPostProcessor对象
            // 方便统一执行实现了BeanDefinitionRegistryPostProcessor接口父类的方法
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 处理外部定义的BeanFactoryPostProcessor,将BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor区分开
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果为BeanDefinitionRegistryPostProcessor类型
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    // 强转成BeanDefinitionRegistryPostProcessor
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 如果是BeanDefinitionRegistryPostProcessor类型,直接执行postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    // 如果不是BeanDefinitionRegistryPostProcessor类型
                    // 则将外部集合中的BeanFactoryPostProcessor存放到regularPostProcessors用于后续一起执行
                    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.
            // 此处的currentRegistryProcessors存放当前需要执行的BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // TODO 首先,调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor。
            // 获取所有实现了BeanDefinitionRegistryPostProcessor接口的类名
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断当前类是否实现了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 将BeanDefinitionRegistryPostProcessor存入currentRegistryProcessors
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 提前存放到processedBeans,避免重复执行,但是此处还未执行
                    processedBeans.add(ppName);
                }
            }
            // 对currentRegistryProcessors接口中的BeanDefinitionRegistryPostProcessor进行排序,方便后续执行
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors集合,用于后续执行父接口的postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历集合,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕后,将currentRegistryProcessors清空
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // TODO 接下来,调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。
            // 这里为什么要再次获取BeanDefinitionRegistryPostProcessor
            // 是因为有可能在上面方法执行过程中添加了BeanDefinitionRegistryPostProcessor,所以这里再次获取
            // 而下面处理BeanFactoryPostProcessor的时候又不需要重复获取了是为什么呢?
            // 因为添加BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor只能在BeanDefinitionRegistryPostProcessor
            // 中添加,在BeanFactoryPostProcessor是无法添加的,具体看方法参数就懂了
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判断当前bean没有被执行过,并且实现了Ordered接口
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // getBean() 如果BeanFactory中没有该Bean则会去创建该Bean
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            // 以下操作和上面是一样的,排序-->添加到registryProcessors-->执行-->清空currentRegistryProcessors
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // TODO 最后处理没有实现Ordered与PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 再次获取BeanDefinitionRegistryPostProcessor
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        // 将本次要执行的BeanDefinitionRegistryPostProcessor存放到currentRegistryProcessors
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        // 提前存放到processedBeans,避免重复执行
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                // 此处的排序已经没有意义了
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // 将本次执行的BeanDefinitionRegistryPostProcessor添加到registryProcessors
                registryProcessors.addAll(currentRegistryProcessors);
                // 执行
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 清空
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // TODO 现在,调用到目前为止处理的所有处理器的 postProcessBeanFactory 回调。
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // Invoke factory processors registered with the context instance.
            // BeanFactory如果不归属于BeanDefinitionRegistry类型,则直接执行beanFactoryPostProcessor
            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.
        // 用于存放实现了priorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了ordered接口的BeanFactoryPostProcessor名称
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 用于存放无排序的BeanFactoryPostProcessor名称
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            // 如果已经执行过了,则不做处理
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            // 如果实现了PriorityOrdered
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            // 如果实现了Ordered
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            // 无排序
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        // TODO 首先,调用实现 PriorityOrdered 的 BeanFactoryPostProcessor。
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // TODO 接下来,调用实现 Ordered 的 BeanFactoryPostProcessors。
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // TODO 最后,调用所有其他 BeanFactoryPostProcessor。
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        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();
    }

总的来说回去执行实现了BeanFactoryPostProcessor接口的类重写的方法,直接说最重要的一个子类-ConfigurationClassPostProcessor 来看看详解:

java复制代码public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); //获取所有的BeanDefinitionName String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); // https://docs.spring.io/spring/docs/5.1.8.RELEASE/spring-framework-reference/core.html#beans-java-basic-concepts // Full @Configuration vs “lite” @Bean mode if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } // 校验是否为配置类 // 配置类分为两种 Full @Configuration vs “lite” @Bean mode // 校验之后在 BeanDefinition 中添加标志属性 // 如果满足条件则加入到configCandidates else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { // 如果是配置类,就放到 configCandidates 变量中 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; // 传入的 registry 是 DefaultListableBeanFactory if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet) { //获取自定义BeanNameGenerator,一般情况下为空 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 // new ConfigurationClassParser,用来解析 @Configuration 类 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); // 将 configCandidates 转成 set candidates , 去重 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()); } // Import类,@Bean,@ImportResource 转化为 BeanDefinition this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); // 再获取一下容器中BeanDefinition的数据,如果发现数量增加了,说明有新的BeanDefinition被注册了 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(); } }

图片1.png

点进去看一下。

image.png

再点进去。

image.png

在这里会拿到主启动类,然后再去扫描主启动类下面的Bean。

从这里进去。

image.png

这就很清晰了,去获取项目中所有使用了@Component注解Bean。

image.png

当然,这个类ConfigurationClassParser里面不止扫描使用了@Component注解的Bean。还有@Bean注解等等,如图

image.png

光是知道在哪里把使用了这些注解的Bean解析出来还不够,需要知道怎么解析出来的,就像我们学习Spring的时候那样,是通过应用上下文扫描出来的,如图

image.png

点进this.componentScanParser.parse这个方法

image.png

可以看到new ClassPathBeanDefinitionScanner,在这里new了一个应用上下文扫描,这就是原理。 而且和我们介绍context = this.createApplicationContext()方法,里面构造函数创建的两个应用上下文中的一个是一样的。

至此项目中所有的Bean都被invokeBeanFactoryPostProcessors这个方法(ConfigurationClassPostProcessor最关键)解析出来。

image.png

并且通过this.reader.loadBeanDefinitions(configClasses);这个方法放到DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap,如图

图片2.png

点进去,再点进这个方法,

图片3.png

再点进这个方法,可以看到现在将我beanNamegetgiao的Bean注册到DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap里面。

图片4.png

如图:

image.png

七,this.finishBeanFactoryInitialization(beanFactory)

这个方法是将DefaultListableBeanFactory这个类里面的beanDefinitionNamesbeanDefinitionMap初始化的,包括Spring三级缓存啊,这个下次再讲了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值