乐趣区

关于java:Spring加载基本概念

Spring 加载流程

这篇文章咱们大略的理解下 Spring 加载流程。

根底概念

1.bean

bean: 说白了就是把一个个实体对象交由 spring 去创立和治理

2.beanDefinition

beanDefinition 是 bean 的定义。有点像 spring 对象的 ”Class”。

3.BeanFactory,ApplicationContext

BeanFactory 是一个根底的容器。ApplicationContext 是 BeanFactory 的一个子接口,性能跟弱小,是高级的容器。

4.BeanFactoryPostProcessor ,BeanDefinitionRegistryPostProcessor

两者都是后置处理器。是 Spring 很重要的拓展点。这两个扩大点的触发机会,都是在 BeanDefinition 加载之后,Bean 实例化之前。
官网倡议是 BeanDefinitionRegistryPostProcessor 用来增加 BeanDefinition,BeanFactoryPostProcessor 用于批改 BeanDefinition。BeanDefinitionRegistryPostProcessor 优先于 BeanFactoryPostProcessor 执行。

5.BeanPostProcessor

BeanPostProcessor 是 bean 的后置处理器,也是 Spring 重要的拓展点。它的触发机会是 Bean 的初始化。postProcessBeforeInitialization 初始化前解决,postProcessAfterInitialization 初始化后处理。

6.InitializingBean

InitializingBean 实现了 afterPropertiesSet 办法就会在 bean 初始化时被调用

7.BeanFactory ,FactoryBean

为什么要把这两个放在一起,因为他们长得像,除了像,没有其余半毛钱关系。BeanFactory 时根底容器,FactoryBean 是一个非凡的 bean,是一个工厂 bean。也是 Spring 的一个重要的拓展点,通过这个类的 getObject() 办法创立一个实列对象。很多插件其实就是用的这个,例如 mybatis 的 Mapper 是一个接口,没有具体的实现却能够操作数据库,其实时 FactoryBean 给它产生了一个代理类。

加载根本流程

public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();
    stopWatch.start();

    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();

    configureHeadlessProperty();

    // 第一步:获取并启动监听器
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    
    try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

        // 第二步:依据 SpringApplicationRunListeners 以及参数来筹备环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);
        configureIgnoreBeanInfo(environment);

        // 筹备 Banner 打印器
        Banner printedBanner = printBanner(environment);

        // 第三步:创立 Spring 容器
        context = createApplicationContext();

        exceptionReporters = getSpringFactoriesInstances(
                SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class}, context);

        // 第四步:Spring 容器前置解决
        prepareContext(context, environment, listeners, applicationArguments,printedBanner);

        // 第五步:刷新容器
        refreshContext(context);
     // 第六步:Spring 容器后置解决
        afterRefresh(context, applicationArguments);

      // 第七步:收回完结执行的事件
        listeners.started(context);
        // 第八步:执行 Runners
        this.callRunners(context, applicationArguments);
        stopWatch.stop();
        // 返回容器
        return context;
    }
    catch (Throwable ex) {handleRunFailure(context, listeners, exceptionReporters, ex);
        throw new IllegalStateException(ex);
    }
}

createApplicationContext() 这里创立容器,增加一些特定的后置处理器。其中就包含了咱们前面要说的 ConfigurationClassPostProcessor 这个后置处理器,也能够说它是 spring 加载中最重要的后置处理器。
refreshContext(context) 这个办法是咱们须要重点关注的,这个办法外面就是将咱们的对象交由 spring 容器去治理,外围办法。

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.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);

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                /**
                 * 激活各种 BeanFactory 处理器, 包含 BeanDefinitionRegistryBeanFactoryPostProcessor 和一般的 BeanFactoryPostProcessor
                 * 执行对应的 postProcessBeanDefinitionRegistry 办法 和  postProcessBeanFactory 办法
                 */
                invokeBeanFactoryPostProcessors(beanFactory);

                /**
                  * 注册拦挡 Bean 创立的 Bean 处理器,即注册 BeanPostProcessor,不是 BeanFactoryPostProcessor,留神两者的区别
                  * 留神,这里仅仅是注册,并不会执行对应的办法,将在 bean 的实例化时执行对应的办法
                  */
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();

                // 国际化
                initMessageSource();

                // 初始化事件和监听
                initApplicationEventMulticaster();

                // 拓展点
                onRefresh();

                // 注册事件监听
                registerListeners();

                // 初始化 bean
                finishBeanFactoryInitialization(beanFactory);

                // 公布容器初始化实现音讯
                finishRefresh();}

            catch (BeansException ex) {if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization -" +
                            "cancelling refresh attempt:" + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
                contextRefresh.end();}
        }

invokeBeanFactoryPostProcessors(beanFactory), 这个办法会激活 BeanDefinitionRegistryPostProcessor 的后置处理器,其中就有就包含
ConfigurationClassPostProcessor 这个类,它会将符合条件的 bean 转化为 beanDefinition。
finishBeanFactoryInitialization(beanFactory), 这个办法将会依据 BeanDefinition 去初始化 bean, 这一步实现后咱们的 bean 就由 spring 接管了。

退出移动版