zoukankan      html  css  js  c++  java
  • Springboot热部署原理

    一、配置加载

        public static void main(String[] args) {
            ConfigurableApplicationContext ctx = SpringApplication.run(SampleTomcatApplication.class, args);
            String foo = ctx.getEnvironment().getProperty("foo");
            System.out.println(foo);
        }

    打印结果

    aaa,bbb

    源码解析

    1、我们在idea环境配置的参数Program arguments上配置的参数,就会被传进main方法的args中

        //封装命令行参数
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        
        public DefaultApplicationArguments(String... args) {
            Assert.notNull(args, "Args must not be null");
            this.source = new Source(args);
            this.args = args;
        }
        Source(String[] args) {
            super(args);
        }
        public SimpleCommandLinePropertySource(String... args) {
            super(new SimpleCommandLineArgsParser().parse(args));
        }
        //解析命令行参数
        public CommandLineArgs parse(String... args) {
            CommandLineArgs commandLineArgs = new CommandLineArgs();
            for (String arg : args) {
                //固定格式
                if (arg.startsWith("--")) {
                    String optionText = arg.substring(2);
                    String optionName;
                    String optionValue = null;
                    int indexOfEqualsSign = optionText.indexOf('=');
                    if (indexOfEqualsSign > -1) {
                        optionName = optionText.substring(0, indexOfEqualsSign);
                        optionValue = optionText.substring(indexOfEqualsSign + 1);
                    }
                    else {
                        optionName = optionText;
                    }
                    if (optionName.isEmpty()) {
                        throw new IllegalArgumentException("Invalid argument syntax: " + arg);
                    }
                    commandLineArgs.addOptionArg(optionName, optionValue);
                }
                else {
                    commandLineArgs.addNonOptionArg(arg);
                }
            }
            return commandLineArgs;
        }

    解析完命令行参数,最终放入到了PropertySource的source属性中,代码就不放了

    2、构建环境

    ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
            //创建并配置相应的环境,获取对应的ConfigurableEnvironment
            ConfigurableEnvironment environment = getOrCreateEnvironment();
            //根据用户配置,配置 environment系统环境
            configureEnvironment(environment, applicationArguments.getSourceArgs());

    创建环境

    //根据环境创建对应ConfigurableEnvironment
        private ConfigurableEnvironment getOrCreateEnvironment() {
            if (this.environment != null) {
                return this.environment;
            }
            switch (this.webApplicationType) {
            case SERVLET://Web程序
                return new StandardServletEnvironment();
            case REACTIVE://响应式web环境
                return new StandardReactiveWebEnvironment();
            default://普通程序
                return new StandardEnvironment();
            }
        }

    都继承自AbstractEnvironment

    public abstract class AbstractEnvironment implements ConfigurableEnvironment {
        
        //初始化配置文件source对象
        private final MutablePropertySources propertySources = new MutablePropertySources();
        
        //初始化了配置文件解析器
        private final ConfigurablePropertyResolver propertyResolver =
                new PropertySourcesPropertyResolver(this.propertySources);
    
        ···
    }

    解析配置文件,并配置到环境中

        protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
            if (this.addConversionService) {
                ConversionService conversionService = ApplicationConversionService.getSharedInstance();
                environment.setConversionService((ConfigurableConversionService) conversionService);
            }
            // 将main 函数的args封装成 SimpleCommandLinePropertySource 加入environment中。
            configurePropertySources(environment, args);
            // 激活相应的配置文件
            configureProfiles(environment, args);
        }
        
        protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
            MutablePropertySources sources = environment.getPropertySources();
            if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
                sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
            }
            if (this.addCommandLineProperties && args.length > 0) {
                String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
                if (sources.contains(name)) {
                    PropertySource<?> source = sources.get(name);
                    CompositePropertySource composite = new CompositePropertySource(name);
                    //解析args,并设置到source属性中,SimpleCommandLinePropertySource继承自PropertySource
                    composite.addPropertySource(
                            new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
                    composite.addPropertySource(source);
                    //存在覆盖的参数,则替换
                    sources.replace(name, composite);
                } else {
                    //解析并设置参数到环境中
                    sources.addFirst(new SimpleCommandLinePropertySource(args));
                }
            }
        }

    获取配置文件属性String foo = ctx.getEnvironment().getProperty("foo");

        public String getProperty(String key) {
            return this.propertyResolver.getProperty(key);
        }

    走的就是AbstractEnvironment方法,通过ConfigurablePropertyResolver的方法获取,具体获取源码也不看了。

    二、热部署

    jar包依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>

  • 相关阅读:
    天兔(Lepus)监控系统慢查询分析平台安装配置
    java怎么用一行代码初始化ArrayList
    yum命令不能使用的相关错误
    【转】Android APP性能测试
    【转】Java经典问题算法大全
    [转]java中Map,List与Set的区别
    关于编写性能高效的javascript事件的技术
    ESLint 规则
    HTML5 使用application cache 接口实现离线数据缓存
    qunit 前端脚本测试用例
  • 原文地址:https://www.cnblogs.com/sglx/p/15673243.html
Copyright © 2011-2022 走看看