Spring Boot源码分析之启动流程

Spring Boot将一个典型的Spring应用的启动流程“模版化”。每个部分使用“可插拔”的模块进行组装。在没有特殊需求的情况下,默认的启动执行流程即可满足需求。如有特殊需求,Spring Boot开放了一系列不同类型的扩展点,我们可以通过这些扩展点对Spring Boot程序的启动,执行和关闭过程进行扩展。

Spring Boot的启动类的main方法中最重要的一句为:

SpringApplication.run(MySpringBootApplication.class, args)

我们就从这里作为入口,基于Spring Boot 1.4.x版本,通过分析run方法的实现来分析Spring Boot的启动流程:

  1. 遍历执行所有通过SpringFactoriesLoader可以查找并加载的SpringApplicationRunListener。并调用他们的started()方法。其中查找所有SpringApplicationRunListener实例的方法为:
	private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
			Class<?>[] parameterTypes, Object... args) {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		// Use names and ensure unique to protect against duplicates
                //此处的type为SpringApplicationRunListener.class ,在classpath的META-INF/spring.factories路径下查找所有
SpringApplicationRunListener的实现类。                                
              Set<String> names = new LinkedHashSet<String>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
              //初始化Listener实例。
              List<T> instances = createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names);
              //如果实现了Ordered接口(按Class,Method,AnnotatedElement查找Ordered)
              AnnotationAwareOrderComparator.sort(instances);
              return instances;

}

   2. 创建并配置当前SpringBoot应用将要使用的Environment:

    1)如果webEnvironment为true,则初始化Environement为StandardServletEnvironment。否则将初始化为StandardEnvironment。

        2)给初始化后的Environment配置PropertySource。

        3)给初始化后的Environment配置Profiles。

	protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
		environment.getActiveProfiles(); // ensure they are initialized
		// But these ones should go first (last wins in a property key clash)
		Set<String> profiles = new LinkedHashSet<String>(this.additionalProfiles);
		profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
		environment.setActiveProfiles(profiles.toArray(new String[profiles.size()]));
	}

       4)给所有的SpringApplicationRunListener调用environmentPrepared方法传入environment。

       5)如果是web服务,则将activeProfiles和所有非SERVLET_ENVIRONMENT_SOURCE_NAMES集合中的属性写入一个空的StandardEnvironment。

  3. 如果bannerMode不为OFF,则打印banner。这一步的用途一般就是为了好玩儿。banner的位置默认在resources下面。默认文件名为banner.txt

  4. 根据用户是否明确设置了applicationContextClass类型以及初始化阶段的推断结果,决定当前SpringBoot应用应该创建什么样的ApplicationContext。如果是web环境,则ApplicationContext初始化为:org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext。如果不是,则ApplicationContext初始化为:org.springframework.context.annotation.AnnotationConfigApplicationContext。

 5. 初始化FailureAnalyzers。load文件spring.factories中的FailureAnalyzer和FailureAnalysisReporter实例,并初始化。用于启动异常时report failure。

 6. 为ApplicationContext设置属性:

    1)设置environment。

    2)注册并初始化BeanNameGenerator和ResourceLoader。此处如果用户没有定义,则使用默认的class。

   3)借助SpringFactoriesLoader查找并加载classpath中所有可用的ApplicationContextInitializer,然后遍历调用这些ApplicationContextInitializer的initialize(applicationContext)方法来对已经创建好的ApplicationContext进行进一步的处理。

  4)遍历调用SpringApplicationRunListener的contextPrepared()方法。将beanNameGenerator,resourceLoader和environment装载入BeanDefinitionLoader方法以后调用load()。然后调用所有SpringApplicationRunListener的contextLoaded()。

    5)refresh Application Context,在这里通过ApplicationContext中refresh()方法调用registerBeanPostProcessors(beanFactory)初始化了所有@EnableAutoConfiguration所加载的配置。

 7.  调用所有的ApplicationRunner和CommandLineRunner的run()。

 8. 调用所有SpringApplicationRunListener的finished()方法。

至此,Spring Boot启动结束。

    原文作者:Spring MVC
    原文地址: https://blog.csdn.net/mytobaby00/article/details/79581650
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞