zoukankan      html  css  js  c++  java
  • springboot启动配置原理以及自定义starter

    录:

    1、springboot启动配置原理
    1.1、创建SpringApplication对象
    1.2、运行run方法
    1.3、事件监听机制
    2、自定义starter
    2.1、自定义starter前的准备工作
    2.2、步骤

    1、springboot启动配置原理    <--返回目录

      几个重要的事件回调机制:
      配置在META-INF/spring.factories

    ApplicationContextInitializer
    SpringApplicationRunListener

      只需要放在ioc容器中

    ApplicationRunner
    CommandLineRunner

    1.1、创建SpringApplication对象    <--返回目录

    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;然后保存起来
        setInitializers((Collection) getSpringFactoriesInstances(
        ApplicationContextInitializer.class));
        //从类路径下找到ETA‐INF/spring.factories配置的所有ApplicationListener
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        //从多个配置类中找到有main方法的主配置类
        this.mainApplicationClass = deduceMainApplicationClass();
    }

    1.2、运行run方法    <--返回目录

    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        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);
            //准备上下文环境;将environment保存到ioc中;而且applyInitializers();
            //applyInitializers():回调之前保存的所有的ApplicationContextInitializer的initialize方法
            //回调所有的SpringApplicationRunListener的contextPrepared();
            prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
            //prepareContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded();
            //刷新容器;ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat);Spring注解版
            //扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
            refreshContext(context);
            //从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
            //ApplicationRunner先回调,CommandLineRunner再回调
            afterRefresh(context, applicationArguments);
            //所有的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);
        }
    }

    1.3、事件监听机制    <--返回目录

      自定义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.xxx.springboot.listener.HelloApplicationContextInitializer
    org.springframework.boot.SpringApplicationRunListener
    = com.xxx.springboot.listener.HelloSpringApplicationRunListener

      自定义ApplicationRunner,只需要放在ioc容器中

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

      自定义CommandLineRunner,只需要放在ioc容器中

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

    2、自定义starter    <--返回目录

    2.1、自定义starter前的准备工作    <--返回目录

    1)、这个场景需要使用到的依赖是什么?
    2)、如何编写自动配置

    @Configuration //指定这个类是一个配置类
    @ConditionalOnXXX //在指定条件成立的情况下自动配置类生效
    @AutoConfigureAfter //指定自动配置类的顺序
    @Bean //给容器中添加组件
    @ConfigurationPropertie结合相关xxxProperties类来绑定相关的配置
    @EnableConfigurationProperties //让xxxProperties生效加入到容器中
    自动配置类要能加载
    将需要启动就加载的自动配置类,配置在META‐INF/spring.factories
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,

    3)、模式:
      启动器只用来做依赖导入;
      专门来写一个自动配置模块;
      启动器依赖自动配置;别人只需要引入启动器(starter)
      mybatis-spring-boot-starter;自定义启动器名-spring-boot-starter

    2.2、步骤    <--返回目录

      1)启动器模块

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atguigu.starter</groupId>
    <artifactId>atguigu-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <!--启动器-->
    <dependencies>
        <!--引入自动配置模块-->
        <dependency>
            <groupId>com.atguigu.starter</groupId>
            <artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    
    </project>

      

      2)自动配置模块

    <?xml version="1.0" encoding="UTF‐8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven‐
    4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atguigu.starter</groupId>
    <artifactId>atguigu‐spring‐boot‐starter‐autoconfigurer</artifactId>
    <version>0.0.1‐SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>atguigu‐spring‐boot‐starter‐autoconfigurer</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring‐boot‐starter‐parent</artifactId>
        <version>1.5.10.RELEASE</version>
        <relativePath/> <!‐‐ lookup parent from repository ‐‐>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF‐8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF‐8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <!‐‐引入spring‐boot‐starter;所有starter的基本配置‐‐>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring‐boot‐starter</artifactId>
        </dependency>
    </dependencies>
    
    </project>
    package com.atguigu.starter;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    @ConfigurationProperties(prefix = "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;
        }
    }
    package com.atguigu.starter;
    public class HelloService {
      HelloProperties helloProperties;
        public HelloProperties getHelloProperties() {
            return helloProperties;
        } 
        public void setHelloProperties(HelloProperties helloProperties) {
            this.helloProperties = helloProperties;
        } 
        public String sayHellAtguigu(String name){
            return helloProperties.getPrefix()+"‐" +name + helloProperties.getSuffix();
        }
    }
    package com.atguigu.starter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    @Configuration
    @ConditionalOnWebApplication //web应用才生效
    @EnableConfigurationProperties(HelloProperties.class)
    public class HelloServiceAutoConfiguration {
        @Autowired
        HelloProperties helloProperties;
        @Bean
        public HelloService helloService(){
            HelloService service = new HelloService();
            service.setHelloProperties(helloProperties);
            return service;
        }
    }

      将需要启动就加载的自动配置类,配置在META‐INF/spring.factories

    ---

  • 相关阅读:
    sed 命令编辑文本
    Iocomp控件教程之Pie Chart——饼状图控件
    《Go并发编程实战》第2版 紧跟Go的1.8版本号
    浅谈PHP数据结构之栈
    oracle11g导入dmp文件(根据用户)
    exp命令ORACLCE10G导出ORACLE11G的数据1455错误
    将war文件解压到指定目录
    JAVA包命名规范
    Eclipse中新建jsp文件访问页面时乱码问题
    网页编码就是那点事
  • 原文地址:https://www.cnblogs.com/xy-ouyang/p/14131038.html
Copyright © 2011-2022 走看看