• springboot启动流程


    @EnableDiscoveryClient
    @SpringBootApplication
    public class ProducerApplication {
    
        public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        //application.setDefaultProperties(Properties properties); 可以设置参数
        ConfigurableApplicationContext context = application.run(args);
       }
    }
    1.创建SpringApplication对象,传入资源问题
        1.1 initialize()初始化容器资源
             1.1.1 将配置资源文件设置个 List<Object> sources对象。
             1.1.2 判断当前是否web环境, 根据查询当前环境中有没有"javax.servlet.Servlet",  "org.springframework.web.context.ConfigurableWebApplicationContext" 字节码文件做判断。
             1.1.3 从META-INF/spring.factories配置文件中加载 ApplicationContextInitializer类,并创建对象,返回对象List赋值给SpringApplication的initializers属性
             1.1.4 从META-INF/spring.factories配置文件中加载 ApplicationListener类,并创建对象, 返回listenter对象的List赋值给SpringApplication的listeners属性。
             1.1.5 判断启动类。    
             (此时可以通过SpringApplication对象设置系统配置, sa.setDefaultProperties(Properties defaultProperties))
        
    2.执行sa.run(args)函数
         2.1 通过configureHeadlessProperty()方法设置"java.awt.headless"属性,先从系统设置中获取,如果取到则不做处理,如果没取到,则设置true进去。
        
        2.2 从META-INF/spring.factories配置文件中加载 SpringApplicationRunListener类,并创建对象, 将listenter对象的List对象作为参数创建
             SpringApplicationRunListeners(listeners)对象实例,并返回。
             
             SpringApplicationRunListener {
                 void starting();
                 void environmentPrepared(ConfigurableEnvironment environment);
                 void contextPrepared(ConfigurableApplicationContext context);
                 void contextLoaded(ConfigurableApplicationContext context);
                 void finished(ConfigurableApplicationContext context, Throwable exception);
              }
             
        2.3 listeners.starting() 执行所有SpringApplicationRunListener的starting()方法。
        
        2.4 设置应用参数。
             ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        
        2.5 准备配置环境。
              ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);
           2.5.1 获取或创建配置环境
             ConfigurableEnvironment environment = getOrCreateEnvironment();
             (1) 如果environment对象已经存在,则直接返回
             (2) 如果不存在,判断webEnvironment(web环境)为true则创建 StandardServletEnvironment对象并返回该对象,否则创建 StandardEnvironment对象并返回。
           2.5.2 设置系统配置参数
             (1) 设置系统资源问题:configurePropertySources(environment, args);
             (2) 获取激活配置文件:configureProfiles(environment, args);
           2.5.3 执行 SpringApplicationRunListeners listeners.environmentPrepared(environment)方法
             (1) 即执行所有SpringApplicationRunListener listener的environmentPrepared()方法。
           2.5.4 如果当前环境非web环境,则对environment进行一次包装。
        
        2.6 设置打印banner
             Banner printedBanner = printBanner(environment);
             
        2.7 判断需要创建的容器类型,并创建context = createApplicationContext();
             2.7.1 判断需要的容器类型
                 contextClass = Class.forName(this.webEnvironment ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
             
             2.7.2 使用反射创建容器并返回
                 (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
        
        2.8 加载失败解析器
             2.8.1 到classpath中 META-INF/spring.factories文件获取 , 并加载类文件并创建实例对象,返回 List<FailureAnalyzer> analyzers;
                 loadFailureAnalyzers(this.classLoader);
             
             2.8.2 准失败分析器, 如何分析器实现了BeanFactoryAware接口,则执行setBeanFactory操作。
                 (1) prepareFailureAnalyzers.prepareFailureAnalyzers(this.analyzers, context);
                 (2) ((BeanFactoryAware) analyzer).setBeanFactory(context.getBeanFactory());
        
        2.9 准备容器
             prepareContext(context, environment, listeners, applicationArguments, printedBanner);
             2.9.1 设置容器环境变量
                  context.setEnvironment(environment);
                 
             2.9.2 设置容器中BeanName解析器,资源加载器
                  postProcessApplicationContext(context);
                 
             2.9.3 执行ApplicationContextInitializer中的initialize(context)方法    
                  applyInitializers(context);
                     initializer.initialize(context);
                     
             2.9.4 执行SpringApplicationRunListener的 contextPrepared(context)方法
                  listeners.contextPrepared(context);
                 
             2.9.5 向容器设置springApplicationArguments对象实例。
                  context.getBeanFactory().registerSingleton("springApplicationArguments",applicationArguments);
                 
             2.9.6 向容器设置banner
                  context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
                 
             2.9.7 设置beanDefination加载器beanDefinationLoader,并解析加载创建bean对象到容器
                 load(context, sources.toArray(new Object[sources.size()]));
                 
             2.9.8  执行SpringApplicationRunListener的 contextLoaded(context)方法
                  listeners.contextLoaded(context);
     
           2.9.9 刷新容器(后续专门解析)
                 refreshContext(context);
         包括加载Beandefination, Beanfactorypostprocess,Beanpostprocess,实现相关接口方法的执行,bean的实例化, bean对象的包装等操作。返回即为装满应用对象的beanFactory.
                 
             2.9.10 容器加载启动完成,执行runner接口的实现类。
                 afterRefresh(context, applicationArguments);
                      callRunners(context, args);
             
             2.9.11 执行SpringApplicationRunListener的 finished(context)方法
                  listeners.finished(context);
                 
             完成,返回容器。   
  • 相关阅读:
    Java常用类之【日期相关类】
    Java常用类之【Math类、Random类、System类、Runtime类】
    Java常用类之【字符串相关类型】
    Java常用类之【八种基本数据类型】
    打印杨辉三角--for循环
    Eclipse设置文字大小
    Eclipse之JSON导包
    Java中设计模式之工厂模式-4
    PC 微信页面倒计时代码 safari不兼容date的问题
    在apache中设置访问目录后进入的默认页面为index.php
  • 原文地址:https://www.cnblogs.com/qq-361807535/p/10707147.html
Copyright © 2020-2023  润新知