首页 > 其他分享 >SpringBoot 1x 系列之(六)Spring Boot启动配置原理

SpringBoot 1x 系列之(六)Spring Boot启动配置原理

时间:2024-02-28 10:14:50浏览次数:30  
标签:... SpringBoot SpringApplicationRunListener 1x void Boot context println public

Spring Boot启动配置原理

启动原理、运行流程、自动配置原理

几个重要的事件回调机制(这几个事件回调机制可供我们进行干预)

配置在META-INF/spring.factories

ApplicationContextInitializer

SpringApplicationRunListener

只需要放在ioc容器中(@Component标注)

ApplicationRunner

CommandLineRunner

启动流程:

1. 创建SpringApplication对象

initialize(sources);
private void initialize(Object[] sources) {
    //保存主配置类
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    //判断当前是否一个web应用
    this.webEnvironment = deduceWebEnvironment();
    //从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来,参考下图的this.initializers
    setInitializers((Collection) getSpringFactoriesInstances(
        ApplicationContextInitializer.class));
    //从类路径下找到META-INF/spring.factories配置的所有ApplicationListener,参考下图的this.listeners
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    //从多个配置类中找到有main方法的主配置类
    this.mainApplicationClass = deduceMainApplicationClass();
}

2. 运行run方法

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   //IOC容器
   ConfigurableApplicationContext context = null;
   FailureAnalyzers analyzers = null;
   configureHeadlessProperty();
    
   //获取SpringApplicationRunListeners;从类路径下META-INF/spring.factories
   SpringApplicationRunListeners listeners = getRunListeners(args);
    //回调所有的SpringApplicationRunListener.starting()方法
   listeners.starting();
   try {
       //封装命令行参数
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
      //准备环境
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
       		//创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
       
      Banner printedBanner = printBanner(environment);
       
       //创建ApplicationContext;决定创建web的ioc容器还是普通的ioc容器
      context = createApplicationContext();
       
      analyzers = new FailureAnalyzers(context);
       
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
     		//进入到prepareContext方法中
      		//准备上下文环境;将environment保存到ioc中;而且applyInitializers();
       		//applyInitializers():回调之前保存的所有的ApplicationContextInitializer的initialize方法
       		//回调所有的SpringApplicationRunListener的contextPrepared();
       		//prepareContext()的最后一步回调所有的SpringApplicationRunListener的contextLoaded();
       
       //刷新容器;ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat);Spring注解版
       //扫描,创建,加载所有组件(配置类,组件,自动配置)
      refreshContext(context);
      afterRefresh(context, applicationArguments);
     		//进入到afterRefresh()中
     		//从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
       		//ApplicationRunner先回调,CommandLineRunner再回调
     
       //所有的SpringApplicationRunListener回调finished方法
      listeners.finished(context, null);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
               .logStarted(getApplicationLog(), stopWatch);
      }
       //整个SpringBoot应用启动完成以后返回启动的ioc容器;
      return context;
   }
   catch (Throwable ex) {
      handleRunFailure(context, listeners, analyzers, ex);
      throw new IllegalStateException(ex);
   }
}

3. 事件监听机制测试

配置在META-INF/spring.factories

ApplicationContextInitializer

public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("ApplicationContextInitializer...initialize..."+applicationContext);
    }
}

SpringApplicationRunListener

public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {

    //必须有的构造器
    public HelloSpringApplicationRunListener(SpringApplication application, String[] args){

    }

    @Override
    public void starting() {
        System.out.println("SpringApplicationRunListener...starting...");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        Object o = environment.getSystemProperties().get("os.name");
        System.out.println("SpringApplicationRunListener...environmentPrepared.."+o);
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...contextPrepared...");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...contextLoaded...");
    }

    @Override
    public void finished(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("SpringApplicationRunListener...finished...");
    }
}

配置(META-INF/spring.factories)

org.springframework.context.ApplicationContextInitializer=\
com.atguigu.springboot.listener.HelloApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
com.atguigu.springboot.listener.HelloSpringApplicationRunListener

只需要放在ioc容器中

ApplicationRunner

@Component
public class HelloApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner...run....");
    }
}

CommandLineRunner

@Component
public class HelloCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner...run..."+ Arrays.asList(args));
    }
}

标签:...,SpringBoot,SpringApplicationRunListener,1x,void,Boot,context,println,public
From: https://www.cnblogs.com/wzzzj/p/18039115

相关文章

  • SpringBoot 1x 系列之(五)SpringBoot与数据访问
    SpringBoot与数据访问JDBC、MyBatis、SpringDataJPASpringBoot底层是使用的SpringData作为数据访问的默认处理方式。1.整合基本JDBC与数据源Pom依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><......
  • SpringBoot 1x 系列之(四)Spring Boot与Web开发
    SpringBoot与Web开发Thymeleaf、Web定制、容器定制1.如何使用SpringBoot创建SpringBoot应用,选中我们需要的模块SpringBoot已经默认将这些场景配置好了,我们只需要在配置文件中指定少量配置就可以运行起来编写业务代码2.SpringBoot对静态资源的映射规则普通的web应用......
  • SpringBoot 1x 系列之(三)SpringBoot与日志
    SpringBoot与日志日志框架、日志配置1.日志框架JDBC和数据库驱动:JDBC是统一的接口层(抽象层),面向JDBC进行开发,而不直接面向数据库驱动,这样的好处是数据库驱动会不断的出现新产品,如果直接面向数据库驱动开发,那么,每次更换数据库驱动,开发的代码就要做相应的调整,而面向JDBC开发,不管......
  • SpringBoot 1x 系列之(二)SpringBoot 配置
    SpringBoot配置配置文件、加载顺序、配置原理1.配置文件SpringBoot默认使用两种类型的配置文件作为一个全局配置文件,配置文件名固定,用于修改SpringBoot自动配置的默认值application.propertiesapplication.y(a)ml1.1YAML简介YAML(YAMLAin'tMarkupLanguage)递归缩写......
  • SpringBoot 1x 系列之(一)SpringBoot 入门
    SpringBoot入门SpringBoot和微服务概念的简介、SpringBootHelloWorld入门程序、内部原理1.SpringBoot简介简化Spring应用开发(整个J2EE开发)的一个框架整个Spring技术栈的一个大整合.........J2EE开发的一站式解决方案注:SpringBoot使用嵌入式的Servlet容器,应用无......
  • spring boot 中使用MybatisPlus的自动填充createTime和updateTime
    首先需要在实体类的字段上加上注解,并且将类型更改为LocalDateTime@TableField(fill=FieldFill.INSERT)@JsonInclude(value=JsonInclude.Include.NON_NULL)@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss")privateLocalDateTimecreateTime;@TableFie......
  • springboot学习过程中的特殊错误
     这是我在学习使用springboot过程中遇到的一个小问题,询问了gpt但是并没有解决我的报错,在网上浏览信息后最终知道了是哪里出了问题 就如这个好哥哥说的一样,mybatis自带的方法不会出现问题,所以问题出在了实体类定义上面,加了@Tableld的注解就解决了问题。......
  • springboot 统一处理请求非法参数
    通过拦截器和过滤器实现,话不多说上代码。1、重写HttpServletRequestWrapper读取body里面的内容。publicclassRequestWrapperextendsHttpServletRequestWrapper{privatefinalStringbody;publicRequestWrapper(HttpServletRequestrequest){super......
  • 如何创建自己的Spring Boot Starter并为其编写单元测试
    当我们想要封装一些自定义功能给别人使用的时候,创建SpringBootStarter的形式是最好的实现方式。如果您还不会构建自己的SpringBootStarter的话,本文将带你一起创建一个自己的SpringBootStarter。快速入门创建一个新的Maven项目。第三方封装的命名格式是xxx-spring-boo......
  • springboot2.6开始禁止循环依赖了
    参考文章: https://mp.weixin.qq.com/s?__biz=MzI0MTUwOTgyOQ==&mid=2247497189&idx=1&sn=0f03cdafad9bacef66c64a490b85ff23&scene=21#wechat_redirect使用了SpringBoot2.6及以上版本的,如果要允许循环依赖,可以作如下设置:方案二:允许循环引用此方案更像是绕过问题而非解决问题......