栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot入门(十二)原理解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot入门(十二)原理解析

目录

第十二章 原理解析

12.1 Profile功能

12.1.1 application-profile功能

12.1.2 @Profile条件装配功能

12.1.3 profile分组

12.2 外部化配置

12.2.1 外部配置源

12.2.2 配置文件查找位置

12.2.3 配置文件加载顺序

12.2.4 关键

12.3 自定义starter

12.3.1 starter启动原理

12.3.2 自定义starter

12.4 SpringBoot原理

12.4.1 SpringBoot启动过程

12.4.2 Application Events and Listeners

12.4.3 ApplicationRunner 与 CommandLineRunner


第十二章 原理解析

12.1 Profile功能

   为了方便多环境适配,springboot简化了profile功能,简化了环境的切换导致需要修改配置文件

12.1.1 application-profile功能

  • 默认配置文件application.yaml,任何时候都会加载
  • 指定环境配置文件application-{env}.yaml
  • 激活指定环境

    配置文件激活命令行激活:java -jar xxx.jar --spring.profiles.active=prod --person.name=haha

    修改配置文件的任意值,命令行优先

  • 默认配置与环境配置同时生效
  • 同名配置项,profile配置优先

    server.port=8080 #同名配置
    
    #在配置文件中指定激活的环境,默认配置文件和指定环境的配置文件都会生效,但是同名属性会覆盖
    spring.profiles.active=prod 

    12.1.2 @Profile条件装配功能

       当加上了@Profile注解,可以使某个环境的条件下这个组件才生效:

    public interface Person {
    
       String getName();
       Integer getAge();
    
    }
    @Profile(value = {"prod","default"}) //prod、default环境下生效
    @Component
    @ConfigurationProperties("person")//读取配置文件中person开头的值
    @Data
    public class Boss implements Person {
    
        private String name;
        private Integer age;
    
    
    }
    @Profile("test")
    @Component
    @ConfigurationProperties("person")
    @Data
    public class Worker implements Person {
    
        private String name;
        private Integer age;
    }

       除了标在类上,也可以标在方法上:

    @Configuration
    public class MyConfig {
    
        @Profile("prod")
        @Bean
        public Color red(){
            return new Color();
        }
    
        @Profile("test")
        @Bean
        public Color green(){
            return new Color();
        }
    }

    12.1.3 profile分组
    spring.profiles.active=myprod
    
    #生产环境组
    spring.profiles.group.myprod[0]=ppd
    spring.profiles.group.myprod[1]=prod
    #测试环境组
    spring.profiles.group.mytest[0]=test

    12.2 外部化配置

       Core Features

       比如把数据库的登录信息等不是固定写死在配置文件中,而实抽取出现写在一个外部配置文件中

    12.2.1 外部配置源

       常用:Java属性文件、YAML文件、环境变量、命令行参数

            比如获取环境变量的值:

    @RestController
    public class HelloController {
        @Value("${MAVEN_HOME}")
        private String msg;
    
        @GetMapping("/msg")
        public String getMsg(){
            return msg+"==>"+osName;
        }
    }

             获取系统的环境变量和属性:

    @SpringBootApplication
    public class Boot09FeaturesProfileApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext run = SpringApplication.run(Boot09FeaturesProfileApplication.class, args);
    
            ConfigurableEnvironment environment = run.getEnvironment();
    
            Map systemEnvironment = environment.getSystemEnvironment();
    
            Map systemProperties = environment.getSystemProperties();
    
            System.out.println(systemEnvironment);
            System.out.println(systemProperties);
        }
    
    }

    12.2.2 配置文件查找位置

       application.properties和application.yaml文件读取位置:

    classpath 根路径

    classpath 根路径下config目录

    jar包当前目录

    jar包当前目录的config目录

    /config子目录的直接子目录

    12.2.3 配置文件加载顺序

      当前jar包内部的application.properties和application.yml

      当前jar包内部的application-{profile}.properties和application-{profile}.yml

      引用的外部jar包的application.properties和application.yml

      引用的外部jar包的application-{profile}.properties和application-{profile}.yml

    12.2.4 关键

       指定环境优先,外部优先,后面的可以覆盖前面的的同名配置项

    12.3 自定义starter

    12.3.1 starter启动原理

  • starter-pom引入autoconfigurer包

    12.3.2 自定义starter

    atguigu-hello-spring-boot-starter(启动器)

    atguigu-hello-spring-boot-starter-autoconfigure(自动配置包)

            pom.xml文件:

    
    
        4.0.0
        
            org.springframework.boot
            spring-boot-starter-parent
            2.4.0
             
        
        com.atguigu
        atguigu-hello-spring-boot-starter-autoconfigure
        0.0.1-SNAPSHOT
        atguigu-hello-spring-boot-starter-autoconfigure
        Demo project for Spring Boot
    
        
            1.8
        
    
        
            
                org.springframework.boot
                spring-boot-starter
            
    
        
    
    
    

       在配置文件中自动注入需要的类:

    public class HelloService {
    
        @Autowired
        HelloProperties helloProperties;
    
        public String sayHello(String userName){
            return helloProperties.getPrefix() + ":"+userName+"》"+helloProperties.getSuffix();
        }
    }
    @ConfigurationProperties("atguigu.hello")
    public class HelloProperties {
    
        private String prefix;
        private String suffix;
    
        public String getPrefix() {
            return prefix;
        }
    
        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    
        public String getSuffix() {
            return suffix;
        }
    
        public void setSuffix(String suffix) {
            this.suffix = suffix;
        }
    }
    @Configuration
    @EnableConfigurationProperties(HelloProperties.class)  //默认HelloProperties放在容器中
    public class HelloServiceAutoConfiguration{
    
        @ConditionalOnMissingBean(HelloService.class)
        @Bean
        public HelloService helloService(){
            HelloService helloService = new HelloService();
            return helloService;
        }
    
    }

            在类路径下创建一个meta-INF文件夹,这个文件夹下有一个文件spring.factories:

    # Auto Configure
    # 指定项目一启动要加载哪个包哪个自动配置类
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.atguigu.hello.auto.HelloServiceAutoConfiguration

       此时可以在其他项目中引入这个自定义的starter场景:

    
        com.atguigu
        atguigu-hello-spring-boot-starter
        1.0-SNAPSHOT
    
    #在配置文件中定义属性atguigu.hello开头
    atguigu.hello.prefix=ATGUIGU
    atguigu.hello.suffix=88888

    12.4 SpringBoot原理

       SpringBoot原理【Spring注解】、SpringMVC原理、自动配置原理、SpringBoot原理

    12.4.1 SpringBoot启动过程

    创建SpringApplication

    保存一些信息利用工具类ClassUtils判定当前应用的类型,一般就是Servlet类型

    bootstrappers初始启动引导器(List):去spring.factories文件中找 org.springframework.boot.Bootstrapper

    找初始化器ApplicationContextInitializer,去spring.factories找ApplicationContextInitializer

    List> initializers找应用监听器ApplicationListener,去spring.factories找ApplicationListener

    List> listeners运行SpringApplication

    StopWatch:监控整个项目的启停记录应用的启动时间createBootstrapContext():创建引导上下文(Context环境)

    获取到所有之前的bootstrappers挨个执行intitialize()来完成对引导启动器上下文环境设置让当前应用进入headless模式,java.awt.headless获取所有RunListener(运行监听器)【为了方便所有Listener进行事件感知】

    getSpringFactoriesInstances去spring.factories找SpringApplicationRunListener遍历SpringApplicationRunListener调用starting方法

    相当于事件通知机制,项目正在starting保存命令行参数,ApplicationArguments

    准备环境prepareEnvironment()

    返回或者创建基础环境信息对象,StandardServletEnvironment

    配置环境信息对象

    读取所有的配置源的配置属性值

    绑定环境信息监听器调用listener.environmentPrepared(),通知所有的监听器当前环境准备完成创建IOC容器,createApplicationContext()

    根据项目类型创建容器,一般为Servlet

    当前Servlet类型会创建AnnotationConfigServletWebServerApplicationContext准备ApplicationContext IOC容器的基本信息,prepareContext()

    保存环境信息

    IOC容器的后置处理流程

    应用初始化器applyInitializers

    遍历所有的ApplicationContextInitializer,调用initialize来对ioc容器进行初始化扩展功能(可以自定义initialize)遍历所有的listener调用contextPrepared,EventPublishRunListenr通知所有的监听器contextPrepared​​​​​​​所有的监听器调用contextLoaded,通知所有的监听器contextLoaded刷新IOC容器,refreshContext

    创建容器中的所有组件(Spring注解)

    容器刷新完成后工作,afterRefresh

    所有监听器调用listeners.started(context),通知所有的监听器started

    调用所有runners,callRunners()

    获取容器中的ApplicationRunner获取容器中的CommandLineRunner合并所有runner并且按照@Order进行排序遍历所有的runner,调用 run 方法

    如果以上有异常

    调用Listener的failed如果没有异常,调用所有监听器的running方法,listeners.running(context),通知所有的监听器runningrunning如果有问题,继续通知failed,调用所有Listener的failed,通知所有的监听器 failed

    12.4.2 Application Events and Listeners

       Core Features

    ApplicationContextInitializer

    ApplicationListener

    SpringApplicationRunListener

       可以自动义组件:在启动过程中某些时机增添自己需要的功能

    public class MyApplicationContextInitializer implements ApplicationContextInitializer {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            System.out.println("MyApplicationContextInitializer ....initialize.... ");
        }
    }
    public class MyApplicationListener implements ApplicationListener {
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            System.out.println("MyApplicationListener.....onApplicationEvent...");
        }
    }
    public class MySpringApplicationRunListener implements SpringApplicationRunListener {
    
        private SpringApplication application;
        public MySpringApplicationRunListener(SpringApplication application, String[] args){
            this.application = application;
        }
    
        @Override
        public void starting(ConfigurableBootstrapContext bootstrapContext) {
            System.out.println("MySpringApplicationRunListener....starting....");
    
        }
    
    
        @Override
        public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
            System.out.println("MySpringApplicationRunListener....environmentPrepared....");
        }
    
    
        @Override
        public void contextPrepared(ConfigurableApplicationContext context) {
            System.out.println("MySpringApplicationRunListener....contextPrepared....");
    
        }
    
        @Override
        public void contextLoaded(ConfigurableApplicationContext context) {
            System.out.println("MySpringApplicationRunListener....contextLoaded....");
        }
    
        @Override
        public void started(ConfigurableApplicationContext context) {
            System.out.println("MySpringApplicationRunListener....started....");
        }
    
        @Override
        public void running(ConfigurableApplicationContext context) {
            System.out.println("MySpringApplicationRunListener....running....");
        }
    
        @Override
        public void failed(ConfigurableApplicationContext context, Throwable exception) {
            System.out.println("MySpringApplicationRunListener....failed....");
        }
    }

    12.4.3 ApplicationRunner 与 CommandLineRunner

       runner接口:

    @FunctionalInterface
    public interface ApplicationRunner {
    
    	
    	void run(ApplicationArguments args) throws Exception;
    
    }
    @FunctionalInterface
    public interface CommandLineRunner {
    
    	
    	void run(String... args) throws Exception;
    
    }

       可以自定义组件:

    @Order(1)
    @Component
    public class MyApplicationRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("MyApplicationRunner...run...");
        }
    }
    @Order(2)
    @Component
    public class MyCommandLineRunner implements CommandLineRunner {
        @Override
        public void run(String... args) throws Exception {
            System.out.println("MyCommandLineRunner....run....");
        }
    }

    PS:根据尚硅谷视频整理,如有侵权,联系删除

  • 转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/732057.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号