【SpringBoot】二、SpringBoot启动流程(源码)

目录

1. 跳到这里,创建SpringApplication对象

(1)SpringApplication构造函数

 2. 创建SpringApplication后执行run方法

(1)SpringApplication#createApplicationContext

(2)SpringApplication#prepareContext

(3)SpringApplication#refreshContext

① prepareBeanFactory

② postProcessBeanFactory

③ invokeBeanFactoryPostProcessors

④ registerBeanPostProcessors

⑤ initMessageSource

⑥ initApplicationEventMessageMulticaster

⑦ onRefresh

⑧ registerListeners

⑨ finishBeanFactoryInitialization

⑩ finishRefresh

总结


基于第一章的Hello World项目。

 一、入口类DemoApplication

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

二、进入SpringApplication的run方法

1. 跳到这里,创建SpringApplication对象

    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }

(1)SpringApplication构造函数

发现个很骚的东西,null强转为ResourceLoader(该类其他地方也出现过null强转),暂且认为除了增强可读性,还便于后续添加新方法时,可以方法重载。

    public SpringApplication(Class<?>... primarySources) {
        // 这个除了可读性,应当是便于后续添加新方法时,可以方法重载
        this((ResourceLoader)null, primarySources);
    }

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        // 初始化属性
        this.sources = new LinkedHashSet();
        this.bannerMode = Mode.CONSOLE;
        this.logStartupInfo = true;
        this.addCommandLineProperties = true;
        this.addConversionService = true;
        this.headless = true;
        this.registerShutdownHook = true;
        this.additionalProfiles = new HashSet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
        this.resourceLoader = resourceLoader;

        // 断言判断非空
        Assert.notNull(primarySources, "PrimarySources must not be null");


        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));

        // 判断当前环境是
        // ① NONE(标准环境(classPath下没有javax.servlet.Servlet以及        
        // org.springframework.web.context.ConfigurableWebApplicationContext)、
        // ② SERVLET(Servlet环境)、
        // ③ REACTIVE(响应式)
        // (这里是SERVLET)
        this.webApplicationType = WebApplicationType.deduceFromClasspath();

        // 扫描当前路径下META-INF/spring.factories文件的,加载ApplicationContextInitializer接口实例
        // 设置初始化器,这些初始化器将在容器刷新前回调,原理是通过SpringFactoriesLoader的loadFactoryNames方法
        // 在 spring.factories文件中找到的ApplicationContextInitializer接口的配置的实现类的全限定类名,并实例化。
        this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));

        // 扫描当前路径下META-INF/spring.factories文件的,加载ApplicationListener接口实例
        // 设置监听器,目的同上
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

        // 去栈帧中寻找方法名为main的方法来得到入口类的名字,反射获取类信息Class,并设置为mainApplicationClass
        // (这里是DemoApplication全类名)
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }

1、ApplicationContextInitializerSpring框架原有的东西,这个类的主要作用就是在ConfigurableApplicationContext类型(或者子类型)的ApplicationContext做refresh之前,允许我们对ConfiurableApplicationContext的实例做进一步的设置和处理

2、在一个Springboot应用中,classpath上会包含很多jar包,有些jar包需要在ConfigurableApplicationContext#refresh()调用之前对应用上下文做一些初始化动作,因此它们会提供自己的ApplicationContextInitializer实现类,然后放在自己的META-INF/spring.factories属性文件中,这样相应的ApplicationContextInitializer实现类就会被SpringApplication#initialize发现。

3、 可以分别实现ApplicationContextInitalizer接口和ApplicationListener接口来印证:

  • 实现两接口:

/**
 * 自定义初始化器
 * @author ZRH
 * @version 1.0.0
 * @date 2020/9/1
 */
public class MyInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("MyInitializer初始化完成");
    }

}
/**
 * 自定义监听器
 * @author ZRH
 * @version 1.0.0
 * @date 2020/9/1
 */
public class MyListener implements ApplicationListener<ApplicationEvent> {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("MyListener");
    }

}
  • 创建META-INF/spring.factories

  •  接着再SpringApplication#getSpringFactoriesInstances方法中
    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes
        , Object... args) {
        ClassLoader classLoader = this.getClassLoader();
        // 加载META-INF/spring.factories得到实现ApplicationContextInitializer接口的所有实现类
        // (ApplicationListener类似)
        Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        // 根据名称利用反射创建实例
        List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader
        , args, names);
        // AnnotationAwareOrderComparator是OrderComparator的子类,
        // 用来支持Spring的Ordered类、@Order注解和@Priority注解。按优先级排序。
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

  • 加载工厂,跳到SpringFactoriesLoader#loadFactoryNames方法,
    public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        String factoryTypeName = factoryType.getName();
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }

  • 再看SpringFactoriesLoader#loadSpringFactories方法
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null 
                ? classLoader.getResources("META-INF/spring.factories") 
                : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    // 找到在项目中得spring.factories完整路径
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    // 读取文件中的属性,即我们写的那两个类
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        // 这里的factoryTypeName依次是接口ApplicationContextInitializer、ApplicationListener
                        String factoryTypeName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils
                        .commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

                        for(int var11 = 0; var11 < var10; ++var11) {
                            // 这里的factoryImplementationName依次是自定义的MyInitializer、MyListener
                            String factoryImplementationName = var9[var11];
                            result.add(factoryTypeName, factoryImplementationName.trim());
                        }
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var13) {
                throw new IllegalArgumentException
                ("Unable to load factories from location [META-INF/spring.factories]", var13);
            }
        }
    }

可以看到,它找的路径便是META-INF/spring.factories,这就是为什么我们在那配置,写死了

此外,classLoader.getResources是调用加载器实例来加载资源,而ClassLoader.getSystemResources是调用系统加载器加载资源;Spring Boot项目打包之后应该用Spring提供的ClassLoader来加载资源(通过自定义类的getClassLoader即可),否则可能会出错。

properties则是读取spring.factories后取得的:

 而且执行顺序自定义META-INF/spring.factories从上到下  >  spring-boot-x.x.x.REALEASE.jar/META-INF/spring.factories   >  spring-boot-autoconfigure-x.x.x.RELEASE.jar/META-INF/spring.factories  >  spring-beans-x.x.x.RELEASE.jar/META-INF/spring.factories。

这种思路就是SPI,一种服务提供发现机制(Service Provider Interface)。大体是,服务的提供者在classpath下的META-INF/services/目录里创建一个以服务接口命名的文件,内容就是这个接口的具体实现类名。当其他的程序需要这个服务时,只需查这个jar包的META-INF/services/中的相应配置文件内容里的具体实现类名,通过反射获取实例,使用该服务。


  • 加载完成之后,就依次得到实现ApplicationContextInitializer接口和ApplicationListener的所有实现类了:

其中:

实现类

作用
ConfigurationWarningsApplicationContextInitializer报告IOC容器的一些常见的错误配置
ContextIdApplicationContextInitializer设置Spring应用上下文的ID
DelegatingApplicationContextInitializer加载 application.properties 中 context.initializer.classes 配置的类
ServerPortInfoApplicationContextInitializer将内置servlet容器实际使用的监听端口写入到 Environment 环境属性中
SharedMetadataReaderFactoryContextInitializer创建一个 SpringBoot 和ConfigurationClassPostProcessor 共用的 CachingMetadataReaderFactory 对象
ConditionEvaluationReportLoggingListener将 ConditionEvaluationReport 写入日志

 


其中: 

实现类作用

ClearCachesApplicationListener

应用上下文加载完成后对缓存做清除工作
ParentContextCloserApplicationListener监听双亲应用上下文的关闭事件并往自己的子应用上下文中传播
FileEncodingApplicationListener检测系统文件编码与应用环境编码是否一致,如果系统文件编码和应用环境的编码不同则终止应用启动
AnsiOutputApplicationListener根据 spring.output.ansi.enabled 参数配置 AnsiOutput
ConfigFileApplicationListener从常见的那些约定的位置读取配置文件
DelegatingApplicationListener监听到事件后转发给 application.properties 中配置的 context.listener.classes 的监听器
ClasspathLoggingApplicationListener对环境就绪事件 ApplicationEnvironmentPreparedEvent 和应用失败事件 ApplicationFailedEvent 做出响应
LoggingApplicationListener配置 LoggingSystem。使用 logging.config 环境变量指定的配置或者缺省配置
LiquibaseServiceLocatorApplicationListener使用一个可以和 SpringBoot 可执行jar包配合工作的版本替换 LiquibaseServiceLocator
BackgroundPreinitializer使用一个后台线程尽早触发一些耗时的初始化任务

 

① 枚举类WebApplicationType的deduceFromClasspath()

该枚举类有三个常量:

    NONE,
    SERVLET,
    REACTIVE;
    static WebApplicationType deduceFromClasspath() {
        if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) 
        && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) 
        && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
            return REACTIVE;
        } else {
            String[] var0 = SERVLET_INDICATOR_CLASSES;
            int var1 = var0.length;

            for(int var2 = 0; var2 < var1; ++var2) {
                String className = var0[var2];
                if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
                    return NONE;
                }
            }

            return SERVLET;
        }
    }

代表着Spring5的两种web技术栈:servlet(Spring MVC)和reactive(Spring WebFlux)。

REACTIVE是响应式编程的东西,指的是应用WebFlux框架下的应用环境,是NIO同步非阻塞IO,未来可能替代当前的MVC


 2. 创建SpringApplication后执行run方法

public ConfigurableApplicationContext run(String... args) {

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        ConfigurableApplicationContext context = null;


        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();

        this.configureHeadlessProperty();


        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();

        Collection exceptionReporters;
        try {

            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);

            this.configureIgnoreBeanInfo(environment);


            Banner printedBanner = this.printBanner(environment);


            context = this.createApplicationContext();


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


            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);


            this.refreshContext(context);

            // 刷新后的处理,是个空实现
            this.afterRefresh(context, applicationArguments);


            stopWatch.stop();

            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass))
                .logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);


            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }
  • 计时

计时器,监控启动时间

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
  • 异常解析器集合的初始化

SpringBootExceptionReporter是一个异常解析器,实现类只有一个是FailureAnalyzers,用于打印异常信息,这个集合在下面new DefaultApplicationArguments处初始化,集合里面装了针对各式各样的异常解析器,在catch到异常后,会遍历这个集合,寻找合适的异常解析器,然后打印异常日志。

Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
  • 容器运行期间的事件监听

内部调getSpringFactoriesInstances方法,取spring.factories中所有的SpringApplicationRunListener,对外暴露封装所有的SpringApplicationRunListener的SpringApplicationRunListeners,用于容器启动间的事件发布到所有的SpringApplicationRunListener中。

SpringApplicationRunListener与ApplicationListener的区别是SpringApplicationRunListener比ApplicationListener更靠前,SpringApplicationRunListener监听的是SpringApplication相关方法的执行属于第一层监听器,他会发布相应的事件给ApplicationListener
 

SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
  • 初始化Environment

根据不同的webApplicationType完成Environment的初始化,一般是使用StandardServletEnvironment实现类,Environment用于描述应用程序当前的运行环境,其抽象了两个方面的内容:配置文件(profile)和属性(properties),其实就是对应的配置文件、环境变量、命令行参数里面的内容。这里Environment构建完成时发布了environmentPrepared事件,并且将最新的配置值绑定到了SpringbootApplication中,也就是当前的对象中。比如yml里面配的spring. main开头的一些属性值。

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
  • 设置Banner

打印Banner,会判断模式是否为隐藏MODE.OFF),不是则打印到控制台,可自定义Banner在类路径下的banner.txt。

Banner printedBanner = this.printBanner(environment);
  • 创建ApplicationContext

根据webApplicationType,反射创建不同的ApplicationContext实现(这里Servlet是AnnotationConfigServletWebServerApplicationContext,在他的父类GenericApplicationContext构造方法中,其中注入了一个DefaultListableBeanFactory,这个BeanFactory很关键,实际上AnnotationConfigServletWebServerApplicationContext的BeanFactory能力就是从DefaultListableBeanFactory扩展而来。

在这一步中也注册了ConfigurationClassPostProcessor、DefaultEventListenerFactory、EventListenerMethodProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor这些beanDefinition,作为基础组件ConfigurationClassPostProcessor是BeanFactoryPostProcessor,负责在容器刷新时加载扫描配置类注解进行组件解析注册BeanDefinition

context = this.createApplicationContext();
  • 获取异常报告事件监听

获取异常报告事件监听,创建流程是通过SpringFactoriesLoader获取到所有实现SpringBootExceptionReporter接口的class。

exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class
    , new Class[]{ConfigurableApplicationContext.class}, context);
  • 初始化ApplicationContext

① 将准备好的Environment设置给ApplicationContext

② 进一步执行ApplicationContext的后置处理,包括注册BeanName生成器设置资源加载器和类加载器设置类型转换器ConversionService等

遍历调用所有的ApplicationContextInitializer的initialize()方法来对已经创建好的ApplicationContext进行进一步的处理。

调用SpringApplicationRunListener的contextPrepared()方法,通知所有的监听者:ApplicationContext已经准备完毕。

⑤ 创建启动类的beanDefiniton注册到容器中。

调用SpringApplicationRunListener的contextLoaded()方法,通知所有的监听者:ApplicationContext已经装载完毕。

this.refreshContext(context);
  • 计时结束
stopWatch.stop();
  • 运行器回调

即实现了ApplicationRunner接口或CommandLineRunner接口的bean

this.callRunners(context, applicationArguments);

(1)SpringApplication#createApplicationContext

根据web应用的类型来创建上下文对象

    protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
            try {
                switch(this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName
        ("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
                    break;
                case REACTIVE:
                    contextClass = Class.forName
        ("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
                    break;
                default:
                    contextClass = Class.forName
        ("org.springframework.context.annotation.AnnotationConfigApplicationContext");
                }
            } catch (ClassNotFoundException var3) {
                throw new IllegalStateException
        ("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
            }
        }

        return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
    }

这里是生成AnnotationConfigServletWebServerApplicationContext

    public AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory) {
        super(beanFactory);
        this.annotatedClasses = new LinkedHashSet();
        // 创建Spring核心组件
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

(2)SpringApplication#prepareContext

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment
        , SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments
        , Banner printedBanner) {
        // 设置标准servlet环境
        context.setEnvironment(environment);
        this.postProcessApplicationContext(context);
        // 添加之前的那些初始化器
        this.applyInitializers(context);
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            this.logStartupInfo(context.getParent() == null);
            this.logStartupProfileInfo(context);
        }
        // 创建默认bean工厂类
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        if (printedBanner != null) {
            beanFactory.registerSingleton("springBootBanner", printedBanner);
        }

        if (beanFactory instanceof DefaultListableBeanFactory) {
            // 默认为false,即不支持名称相同的bean被覆盖
            ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding
            (this.allowBeanDefinitionOverriding);
        }

        // 默认不延迟初始化
        if (this.lazyInitialization) {
            context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
        }

        // 加载资源
        Set<Object> sources = this.getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        this.load(context, sources.toArray(new Object[0]));
        listeners.contextLoaded(context);
    }

(3)SpringApplication#refreshContext

 

直接跳到AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            // 初始化前的预处理,初始化Environment里面的PropertySources
            this.prepareRefresh();

            // 获取BeanFactory,直接返回的是前面初始化的beanFactory,只不过设置了一下SerializationId
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();


            this.prepareBeanFactory(beanFactory);

            try {
                

                this.postProcessBeanFactory(beanFactory);

                
                this.invokeBeanFactoryPostProcessors(beanFactory);

                // 注册bean的后置处理器
                this.registerBeanPostProcessors(beanFactory);

                // 初始化MessageSource组件。MessageSource组件主要用来实现国际化、消息解析处理。
                this.initMessageSource();

                // 初始化事件派发器
                this.initApplicationEventMulticaster();

                //  留给子类重写
                this.onRefresh();

                // 注册事件监听器
                this.registerListeners();

                // 初始化所有剩下的单例Bean
                this.finishBeanFactoryInitialization(beanFactory);

                // 完成容器的创建工作
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                // 清除缓存
                this.resetCommonCaches();
            }

        }
    }

① prepareBeanFactory

BeanFactory的预处理配置

 

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());

        // 设置BeanFactory的类加载器、表达式解析器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory
        .getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));

        
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));


        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);


        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);


        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        // 添加AspectJ
        if (beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }


        if (!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if (!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if (!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

    }

上述代码中:

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 

在容器注册了ApplicationContextAwareProcessor这个Bean后置处理器,用于处理实现了XXXAware接口的bean,调用其setXXX方法。这个Bean后处理器将实现了其下几个Aware的bean分别回调对应的方法。


配置ignoreDependencyInterface,即忽略这些自动注入,但实测@Autowired注入时还是能装配。避免这些beanDefinition设置了自动注入(即AutowireMode)。若自动注入生效,该Bean的setXXX方法将被自动注入,那么为了避免和XXXAware接口冲突,应进行了忽略。

        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

添加一些自动注入支持,包含BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext

        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

配置一个可加载所有监听器的组件,用于收集所有实现了ApplicationListener接口的bean并收集到容器中的一个集合中

        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

注册了默认的运行时环境、系统配置属性、系统环境的信息。

        if (!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if (!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if (!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment"
                , this.getEnvironment().getSystemEnvironment());
        }

       

② postProcessBeanFactory

准备BeanFactory完成后进行的后置处理 

servlet为例,这里的ApplicationContext实现实际上为AnnotationConfigServletWebServerApplicationContext。在该类中该方法主要是完成了:

AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory:

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.postProcessBeanFactory(beanFactory);
        if (this.basePackages != null && this.basePackages.length > 0) {
            this.scanner.scan(this.basePackages);
        }

        if (!this.annotatedClasses.isEmpty()) {
            this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }

    }

ServletWebServerApplicationContext#postProcessBeanFactory:

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        this.registerWebApplicationScopes();
    }

其中:往容器注册了一个bean的后置处理器处理ServletContextAware和ServletConfigAware,用于注入ServletContext和ServletConfig。

beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));

 往容器注册Scope,Scope描述的是Spring容器如何新建Bean实例的,这里注册了Request以及Session两个Scope并且注册ServletRequest、ServletResponse、HttpSession、WebRequest为自动装配。

this.registerWebApplicationScopes();

当判断容器的basePackages属性不为null的时候进行包扫描。

当判断容器的annotatedClasses属性不为null也进行注册。

         if (this.basePackages != null && this.basePackages.length > 0) {
            this.scanner.scan(this.basePackages);
        }

        if (!this.annotatedClasses.isEmpty()) {
            this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }

③ invokeBeanFactoryPostProcessors

执行BeanFactory创建后的后置处理器,这一步里面会处理ConfigurationClassPostProcessor这个beanDefinition后置处理器完成所有的beanDefinition注册

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 执行BeanFactory后置处理器
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory
            , this.getBeanFactoryPostProcessors());
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

    }

获取已经注册到容器的beanFactoryPostProcessor的beanFactoryPostProcessors(这里用了容器内beanFactoryPostProcessors这个变量存的而不是从beanDefinition获取的)

 调用了PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory
        , List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    // 用于存放已经执行了的后置处理器名
    Set<String> processedBeans = new HashSet();

    ArrayList regularPostProcessors;
    ArrayList registryProcessors;
    int var9;
    ArrayList currentRegistryProcessors;
    String[] postProcessorNames;

    // 这里要判断BeanFactory的类型,默认SpringBoot创建的BeanFactory是DefaultListableBeanFactory,它便是。
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        regularPostProcessors = new ArrayList();
        registryProcessors = new ArrayList();

        // 遍历已经注册到beanFactory的BeanFactoryPostProcessor后置处理器
        // ,然后分类为regularPostProcessors和registryProcessors
        Iterator var6 = beanFactoryPostProcessors.iterator();
        while (var6.hasNext()) {
            BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor) var6.next();

            // 获取容器内已注册的beanDefinition中BeanDefinitionRegistryPostProcessor类型的bean
            // 筛选实现PriorityOrdered接口的,再排序,然后回调其postProcessBeanDefinitionRegistry。
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;


                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            } else {
                regularPostProcessors.add(postProcessor);
            }
        }


         // 这个currentRegistryProcessors变量用于分阶段执行方法,因为有PriorityOrdered和Ordered接口的存在。
        currentRegistryProcessors = new ArrayList();


         // 下面几大段代码:获取容器内已注册的beanDefinition中BeanDefinitionRegistryPostProcessor类型的bean
        // 并添加到processedBeans,会根据是否实现PriorityOrdered接口、Ordered接口进行排序(大体顺序是
        // PriorityOrdered > Ordered > 没实现接口的,而同一接口的按方法返回值确定顺序),
        // 然后调用invokeBeanDefinitionRegistryPostProcessors执行其postProcessBeanDefinitionRegistry方法。
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class
                , true, false);
        String[] var16 = postProcessorNames;
        var9 = postProcessorNames.length;

        int var10;
        String ppName;
        for (var10 = 0; var10 < var9; ++var10) {
            ppName = var16[var10];
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName
                        , BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }


        //排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);

        //添加到registryProcessors
        registryProcessors.addAll(currentRegistryProcessors);

        //执行
        // 这里面会执行最重要的ConfigurationClassPostProcessor,他会对当前beandifinitonMap中的带有configraution注解的
        // 进行处理,比如处理@Component 、@ComponentScan 、@Import 、@ImportResource、@PropertySource 、@Bean注解,
        // 注册所有的beanDefinition
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();


        // 接下来,调用实现Ordered接口的BeanDefinitionRegistryPostProcessors。
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class
                , true, false);
        var16 = postProcessorNames;
        var9 = postProcessorNames.length;

        for (var10 = 0; var10 < var9; ++var10) {
            ppName = var16[var10];
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName
                        , BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }


        //排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);

        //添加到registryProcessors
        registryProcessors.addAll(currentRegistryProcessors);

        // 执行
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();


        // 最后,调用所有其他BeanDefinitionRegistryPostProcessor(没实现上面两接口的)
        boolean reiterate = true;

        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class
                    , true, false);
            String[] var19 = postProcessorNames;
            var10 = postProcessorNames.length;

            for (int var26 = 0; var26 < var10; ++var26) {
                String ppName = var19[var26];
                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();
        }


        // 回调所有BeanFactoryPostProcessor的postProcessBeanFactory方法:
        // 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
        // 再调用BeanFactoryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors((Collection) registryProcessors
                , (ConfigurableListableBeanFactory) beanFactory);
        invokeBeanFactoryPostProcessors((Collection) regularPostProcessors
                , (ConfigurableListableBeanFactory) beanFactory);


    } else {

        // 如果BeanFactory没有实现BeanDefinitionRegistry接口
        // 调用在上下文实例中注册的工厂处理器。
        invokeBeanFactoryPostProcessors((Collection) beanFactoryPostProcessors
                , (ConfigurableListableBeanFactory) beanFactory);
    }


    // 下面的部分是回调BeanFactoryPostProcessor,思路与上面的几乎一样
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class
            , true, false);
    regularPostProcessors = new ArrayList();
    registryProcessors = new ArrayList();
    currentRegistryProcessors = new ArrayList();
    postProcessorNames = postProcessorNames;
    int var20 = postProcessorNames.length;

    String ppName;
    for (var9 = 0; var9 < var20; ++var9) {
        ppName = postProcessorNames[var9];
        if (!processedBeans.contains(ppName)) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                registryProcessors.add(ppName);
            } else {
                currentRegistryProcessors.add(ppName);
            }
        }
    }

    sortPostProcessors(regularPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors((Collection) regularPostProcessors
            , (ConfigurableListableBeanFactory) beanFactory);
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size());
    Iterator var21 = registryProcessors.iterator();

    while (var21.hasNext()) {
        String postProcessorName = (String) var21.next();
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }

    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors((Collection) orderedPostProcessors
            , (ConfigurableListableBeanFactory) beanFactory);
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());
    Iterator var24 = currentRegistryProcessors.iterator();

    while (var24.hasNext()) {
        ppName = (String) var24.next();
        nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    }

    invokeBeanFactoryPostProcessors((Collection) nonOrderedPostProcessors
            , (ConfigurableListableBeanFactory) beanFactory);

     // 清理缓存
    beanFactory.clearMetadataCache();
}

 可以看看类之间的关系:

 看ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry


    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 获取容器Id,获取其是否调用过,如果没有则继续执行processConfigBeanDefinitions
        int registryId = System.identityHashCode(registry);
        if (this.registriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
            "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
        } else if (this.factoriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + registry);
        } else {
            this.registriesPostProcessed.add(registryId);
            this.processConfigBeanDefinitions(registry);
        }
    }

看 ConfigurationClassPostProcessor#processConfigBeanDefinitions

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        List<BeanDefinitionHolder> configCandidates = new ArrayList();


        String[] candidateNames = registry.getBeanDefinitionNames();
        String[] var4 = candidateNames;
        int var5 = candidateNames.length;

        for (int var6 = 0; var6 < var5; ++var6) {
            String beanName = var4[var6];
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
                if (this.logger.isDebugEnabled()) {
                    this.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));
            }
        }

        if (!configCandidates.isEmpty()) {

            // 对配置类进行排序
            configCandidates.sort((bd1, bd2) -> {
                int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
                int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
                return Integer.compare(i1, i2);
            });

            // 加载获取BeanNameGenerator
            SingletonBeanRegistry sbr = null;
            if (registry instanceof SingletonBeanRegistry) {
                sbr = (SingletonBeanRegistry) registry;
                if (!this.localBeanNameGeneratorSet) {
                    BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                            "org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
                    if (generator != null) {
                        this.componentScanBeanNameGenerator = generator;
                        this.importBeanNameGenerator = generator;
                    }
                }
            }

            if (this.environment == null) {
                this.environment = new StandardEnvironment();
            }

            // 初始化配置类解析器
            ConfigurationClassParser parser = new ConfigurationClassParser(
                    this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader
                    , this.componentScanBeanNameGenerator, registry);

            // 需要解析的配置类集合
            Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);

            //已经解析的配置类集合
            HashSet alreadyParsed = new HashSet(configCandidates.size());

            do {

                // 解析配置类。很关键
                parser.parse(candidates);

                // 校验
                parser.validate();
                Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
                configClasses.removeAll(alreadyParsed);
                if (this.reader == null) {
                    this.reader = new ConfigurationClassBeanDefinitionReader(registry
                            , this.sourceExtractor, this.resourceLoader, this.environment
                            , this.importBeanNameGenerator, parser.getImportRegistry());
                }


                // 将上面解析配置类得到的BeanDefinition注册到BeanDefinitionMap中。
                this.reader.loadBeanDefinitions(configClasses);

                alreadyParsed.addAll(configClasses);
                candidates.clear();
                if (registry.getBeanDefinitionCount() > candidateNames.length) {

                     //当前的beanDefinitinoNames
                    String[] newCandidateNames = registry.getBeanDefinitionNames();

                    //上一次解析之前的beanDefinitinoNames
                    Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
                    
                    //这次解析的beanDefinitinoNames
                    Set<String> alreadyParsedClasses = new HashSet();
                    Iterator var12 = alreadyParsed.iterator();


                    while (var12.hasNext()) {
                        ConfigurationClass configurationClass = (ConfigurationClass) var12.next();
                        alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
                    }

                    String[] var23 = newCandidateNames;
                    int var24 = newCandidateNames.length;

                    // 遍历当前bdNames,若不是以前有的,并且是配置类,并且没有被解析到,则添加到candidates,
                    // 下一次循环再解析一次
                    for (int var14 = 0; var14 < var24; ++var14) {
                        String candidateName = var23[var14];
                        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());

            // 将ImportRegistry注册为Bean,以支持ImportAware 和@Configuration类
            if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
                sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
            }

             // 清除缓存
            if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
                ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
            }

        }
    }

确定配置类和组件:

checkConfigurationClassCandidate()会判断是否为一个配置类,并为BeanDefinition设置属性为lite或者full。如果加了@Configuration,那么对应的BeanDefinition为full;如果加了@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。lite和full均表示这个BeanDefinition对应的类是一个配置类,最后都加入到configCandidates
       

        String[] candidateNames = registry.getBeanDefinitionNames();
        String[] var4 = candidateNames;
        int var5 = candidateNames.length;

        for (int var6 = 0; var6 < var5; ++var6) {
            String beanName = var4[var6];
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
                if (this.logger.isDebugEnabled()) {
                    this.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));
            }
        }

 

由于篇幅原因,上边关于解析注解,让系统完成自动配置功能的实现,放在我的“【SpringBoot】二、SpringBoot启动流程之自动配置(源码)”。

请注意:

解析完配置类后,把结果传给this.reader.loadBeanDefinitions(configClasses);这一步很重要,将beanDefinition注册到beanDefinitionMap,让Spring IOC容器想用时去获取。简单看下源码:

跳到ConfigurationClassBeanDefinitionReader#loadBeanDefinitions,再到ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass,再到ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass,再到DefaultListableBeanFactory#registerBeanDefinition

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 
        throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {

                // 验证beanDefinition,只验证一项内容:beanDefinition不能同时具有overrideMethod
                // 和factoryMethod两个属性,如果两个都有,就验证失败
                ((AbstractBeanDefinition)beanDefinition).validate();

            } catch (BeanDefinitionValidationException var8) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
            }
        }

        // 创建一个临时变量,用于存放之前同名的beanDefinition(如果有的话)
        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        
        // 如果同名了。Spring这里有一个标识位allowBeanDefinitionOverriding,表示是否允许BeanDefinition被覆盖。
        // 一般这个值都是false,除非特定的业务情境下,允许覆盖同名的BeanDefinition。
        // 如果allowBeanDefinitionOverriding是false的话,就抛出异常,表示beanName冲突了
        // 如果allowBeanDefinitionOverriding是true的话,就直接覆盖原来的beanDefinition
        if (existingDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }

            if (existingDefinition.getRole() < beanDefinition.getRole()) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (!beanDefinition.equals(existingDefinition)) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (this.logger.isTraceEnabled()) {
                this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
            }

            // 将beanDefinition放入到beanDefinitionMap中,这个beanDefinition至此加入了SpringIOC(下同)
            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if (this.hasBeanCreationStarted()) {
                synchronized(this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    this.removeManualSingletonName(beanName);
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);

                // 如果没有同名的BeanDefinition,就把beanName放入到beanDefinitionNames集合中
// beanDefinitionNames是一个Set,存储所有BeanDefinition的name,不是别名,是为了加速BeanDefinition的名称检查
                this.beanDefinitionNames.add(beanName);
                this.removeManualSingletonName(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }

        if (existingDefinition == null && !this.containsSingleton(beanName)) {
            if (this.isConfigurationFrozen()) {
                this.clearByTypeCache();
            }
        } else {
            this.resetBeanDefinition(beanName);
        }

    }

添加的语句便是:this.beanDefinitionMap.put(beanName, beanDefinition);这样,就将beanDefinition加入“资源池”beanDefinitionMap,后面Spring IOC在需要的时候,就向资源池要对象,这便是依赖控制反转。

 

④  registerBeanPostProcessors

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

和③类似,

注册bean后置处理器,含MergedBeanDefinitionPostProcessor:

注册逻辑跟注册beanFactoryPostProcessor差不多,注册顺序都会判断priorityOrdered与Ordered接口,并且先注册MergedBeanDefinitionPostProcessor再注册beanFactoryPostProcessor

这里有两个MergedBeanDefinitionPostProcessor,一个是AutowiredAnnotationBeanPostProcessor,一个是ApplicationListenerDetector。

  • AutowiredAnnotationBeanPostProcessor 会解析bean的自动注入属性,判断是否有需要依赖的项,并通过registerExternallyManagedConfigMember注册依赖项。
  • ApplicationListenerDetector 作用,收集一个beanName为键,是否单例为值的map

 

⑤  initMessageSource

messageSource主要是spring提供的国际化组件,

⑥  initApplicationEventMessageMulticaster

这里也是扫描beanDefinition中有没有applicationEventMulticaster,如果没有则使用默认的SimpleApplicationEventMulticaster,这里需要注意的是,在这之前,springboot启动过程中其实也有事件分发,比如SpringApplicationRunListener的start方法在容器开始的时候就被调用了,如何做的?实际上它是使用的内部的SimpleApplicationEventMulticaster来完成的事件广播。而这里和后面将要注册的listener不是使用的同一个事件广播器

⑦  onRefresh

SERVLET类型的web应用就跳到了ServletWebServerApplicationContext#onRefresh

    protected void onRefresh() {
        super.onRefresh();

        try {
            this.createWebServer();
        } catch (Throwable var2) {
            throw new ApplicationContextException("Unable to start web server", var2);
        }
    }

ServletWebServerApplicationContext#createWebServer 

    // 创建web服务
    private void createWebServer() {
        WebServer webServer = this.webServer;
        ServletContext servletContext = this.getServletContext();

        // 刚开始都为null
        if (webServer == null && servletContext == null) {

            // 获取创建容器的工厂,可以通过WebServerFactoryCustomizer接口对这个工厂进行自定义设置
            ServletWebServerFactory factory = this.getWebServerFactory();

            // 创建web容器,这个方法为wrapper设置了servletClass为DispatcherServlet
            this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
            this.getBeanFactory().registerSingleton("webServerGracefulShutdown"
            , new WebServerGracefulShutdownLifecycle(this.webServer));
            this.getBeanFactory().registerSingleton("webServerStartStop"
            , new WebServerStartStopLifecycle(this, this.webServer));
        } else if (servletContext != null) {
            try {
                this.getSelfInitializer().onStartup(servletContext);
            } catch (ServletException var4) {
                throw new ApplicationContextException("Cannot initialize servlet context", var4);
            }
        }

        this.initPropertySources();
    }

看下TomcatServletServiceFactory#getWebServer

    public WebServer getWebServer(ServletContextInitializer... initializers) {
        if (this.disableMBeanRegistry) {
            Registry.disableRegistry();
        }

        // 创建tomcat
        Tomcat tomcat = new Tomcat();

        // 设置工作目录
        File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
        tomcat.setBaseDir(baseDir.getAbsolutePath());

        // 初始化tomcat的连接器,默认NIO模式,可以通过WebServerFactoryCustomizer改变具体模式
        Connector connector = new Connector(this.protocol);
        connector.setThrowOnFailure(true);
        tomcat.getService().addConnector(connector);

        // 自定义连接器
        this.customizeConnector(connector);
        tomcat.setConnector(connector);

        // 设置自动部署为false
        tomcat.getHost().setAutoDeploy(false);

        this.configureEngine(tomcat.getEngine());
        Iterator var5 = this.additionalTomcatConnectors.iterator();

        while(var5.hasNext()) {
            Connector additionalConnector = (Connector)var5.next();
            tomcat.getService().addConnector(additionalConnector);
        }

        // 准备上下文
        this.prepareContext(tomcat.getHost(), initializers);

        // 最后返回一个Tomcat服务器
        return this.getTomcatWebServer(tomcat);
    }

再进TomcatServletWebServerFactory#prepareContext

protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
        File documentRoot = this.getValidDocumentRoot();
        TomcatEmbeddedContext context = new TomcatEmbeddedContext();
        if (documentRoot != null) {
            context.setResources(new TomcatServletWebServerFactory.LoaderHidingResourceRoot(context));
        }

        // 为TomcatEmbeddedContext对象设置属性
        context.setName(this.getContextPath());
        context.setDisplayName(this.getDisplayName());
        context.setPath(this.getContextPath());
        File docBase = documentRoot != null ? documentRoot : this.createTempDir("tomcat-docbase");
        context.setDocBase(docBase.getAbsolutePath());
        context.addLifecycleListener(new FixContextListener());
        context.setParentClassLoader(this.resourceLoader != null ? this.resourceLoader.getClassLoader() 
        : ClassUtils.getDefaultClassLoader());
        this.resetDefaultLocaleMapping(context);
        this.addLocaleMappings(context);

        try {
            context.setCreateUploadTargets(true);
        } catch (NoSuchMethodError var8) {
        }

        this.configureTldSkipPatterns(context);
        WebappLoader loader = new WebappLoader();
        loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
        loader.setDelegate(true);
        context.setLoader(loader);
        if (this.isRegisterDefaultServlet()) {
            this.addDefaultServlet(context);
        }

        if (this.shouldRegisterJspServlet()) {
            this.addJspServlet(context);
            this.addJasperInitializer(context);
        }

        context.addLifecycleListener(new TomcatServletWebServerFactory.StaticResourceConfigurer(context));
        ServletContextInitializer[] initializersToUse = this.mergeInitializers(initializers);
        host.addChild(context);
        this.configureContext(context, initializersToUse);
        this.postProcessContext(context);
    }

⑧ registerListeners

注册监听器,并广播早期事件(只是一个供springboot自己用的一个扩展点,这个扩展点允许在后置处理器和监听器都被创建好,其余的单实例Bean还没有创建时广播一些早期事件),通过debug看这里目前没有任何早期事件存入 

⑨  finishBeanFactoryInitialization

初始化其他的单例bean,解决了循环依赖

⑩ finishRefresh

清除资源缓存(如扫描的ASM元数据)、处理生命周期处理器(Lifecycle接口)、发布容器刷新完成的事件。ServletWebServerApplicationContext在最后会调用 WebServer 的start方法 


总结

一、 创建SpringApplication,包括设置默认属性、web应用类型、初始化器与监听器、入口类的类信息等

二、 run

1. 监控容器启动时间

2. 初始化异常解析器集合

3. 监听容器启动间的事件

4. 根据web应用类型初始化Environment

5. 设置Banner

6. 根据web应用类型创建ApplicationContext,注册基础组件

7. 获取异常报告事件监听

8. prepareContext

        (1)设置配置环境

        (2)创建默认beanFactory类:DefaultListableBeanFactory

        (3)加载资源

9. refreshContext,启动web容器

        (1)prepareBeanFactory

                ① 设置类加载器、表达式解析器

                ② 设置一些自动注入与忽略自动注入的支持

                ③ 注册默认系统信息

        (2)postProcessBeanFactory

                ① 往容器注册WebApplicationContextServletContextAwareProcessor

                ② 往容器注册Scope

                ③ 判断容器的basePackages、annotatedClasses属性是否为null

        (3)invokeBeanFactoryPostProcessors

                ① beanFactory是BeanDefinitionRegistry类型

                        Ⅰ. 遍历已经注册到beanFactory的BeanFactoryPostProcessor后置处理器,然后分类为regularPostProcessors和registryProcessors

                        Ⅱ. 按【实现PriorityOrder接口->Order接口->没实现接口】顺序处理,再分别各自排序,添加到registryProcessors,最后后处理beanDefinition注册表

                                - 没有调用过则继续,去处理配置beanDefinition

                                - 根据@Component 、@ComponentScan 、@Import 、@ImportResource、@Configuration、@Bean等设beanDefinition属性为full或lite

                                - 配置类跑排序

                                - 解析配置类

                                        ➷ 依次处理每个@PropertySource、再是每个@ComponentScan、每个@Import、每个@ImportResource、配置类中@Bean注解的方法、存在父类则递归处理

                                - 将上面解析配置类得到的BeanDefinition注册到BeanDefinitionMap中

                        Ⅲ. 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,再调用BeanFactoryPostProcessor的postProcessBeanFactory方法

                ② BeanFactory非BeanDefinitionRegistry类型,则调用在上下文实例中注册的工厂处理器

        (4)registerBeanPostProcessors

        (5)初始化MessageSource组件

        (6)初始化事件派发器

        (7)创建web容器

        (8)注册事件监听器

        (9)初始化所有剩下的单实例bean

        (10)完成容器的创建工作

10. 停止计时

11. 运行器回调

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

winrh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值