专栏首页Java系列文章springBoot学习(四)项目初始化的开始和结束

springBoot学习(四)项目初始化的开始和结束

ApplicationContextInitializer接口

用来初始化Spring ConfigurableApplicationContext应用上下文的回调接口,是在ConfigurableApplicationContext.refresh()之前调用。 该接口典型的应用场景是web应用中需要编程方式对应用上下文做初始化。比如,注册属性源(property sources)或者针对上下文的环境信息environment激活相应的profile

代码实现

默认的application.properties文件(默认指定为生产环境)
test.name=default
spring.profiles.active=prd
application-dev.properties文件
test.name=dev
application-prd.properties文件
test.name=prd
自定义MyApplicationContextInitializer实现ApplicationContextInitializer接口,重写initialize方法
package com.yxj.spring.Initializer;

import com.yxj.spring.SpringBootTestRun;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.Initializer
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 22:39
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 22:39
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    /**
     * 1.springBoot执行ApplicationContextInitializer refresh方法之前会先执行
     * 2.在方法中设置活动配置文件为dev(该结果可以从其他途径去获取,这里给定默认值dev)
     * 3.在启动类最后获取name,查看最终结果
     * @param applicationContext
     */
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        applicationContext.getEnvironment().setActiveProfiles("dev");
        System.out.println("-------初始化---------");
    }
}
springBoot启动类
package com.yxj.spring;

import com.yxj.spring.Initializer.MyApplicationContextInitializer;
import com.yxj.spring.monitor.MyApplicationListener;
import com.yxj.spring.monitor.MyEvent;
import com.yxj.spring.properties.TestProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

import java.util.List;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/18 20:18
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/18 20:18
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@SpringBootApplication
public class SpringBootTestRun {

    @Value("${test.name}")
    private String testName;

    /**
     * 添加初始化类方式
     * 1.springBootTestRun.addInitializers(new MyApplicationContextInitializer());
     * 2.通过配置项来指定(context.initiallzer.classes=com.yxj.spring.Initializer.MyApplicationContextInitializer)
     * 3.spring.factories机制
     * 应用:
     * 当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入
     * 在日常工作中,我们可能需要实现一些SDK或者Spring Boot Starter给被人使用,这个使用我们就可以使用Factories机制。
     * Factories机制可以让SDK或者Starter的使用只需要很少或者不需要进行配置,只需要在服务中引入我们的jar包。
     * 详细使用参考:http://blog.51cto.com/13836814/2134630
     *
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication springBootTestRun = new SpringApplication(SpringBootTestRun.class);
        //springBootTestRun.addInitializers(new MyApplicationContextInitializer());
        ConfigurableApplicationContext run = springBootTestRun.run(args);
        SpringBootTestRun bean = run.getBean(SpringBootTestRun.class);
        System.out.println("------------分割线------------");
        System.out.println(bean.testName);
        run.close();
    }
}
测试结果
-------初始化---------


------------分割线------------
dev

CommandLineRunner和ApplicationRunner接口

CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调。如果希望在项目启动完成之前,初始化一些操作,可以使用这两个接口。

实现
  • 实现CommandLineRunner或者ApplicationRunner接口
  • 实现run方法
  • 通过@Component或者其他方式添加到spring容器管理中
  • 可以实现多个,通过@Order(value = XXX)的方式,可以实现排序
CommandLineRunner接口

第一个CommandLineRunner

package com.yxj.spring.runner;

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:10
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:10
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 4)
public class MyCommandLineRunner1 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("order value is 4   。MyCommandLineRunner1 run.  get args : "+Arrays.asList(args));
    }
}

第二个CommandLineRunner

package com.yxj.spring.runner;

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:10
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:10
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 1)
public class MyCommandLineRunner2 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("order value is 1   。MyCommandLineRunner2 run.  get args : "+Arrays.asList(args));
    }
}

第一个ApplicationRunner

package com.yxj.spring.runner;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:27
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:27
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 3)
public class MyApplicationRunner1 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        for(String argsString :args.getOptionNames()){
            System.out.println("order value is 3   。MyApplicationRunner1 is ApplicationArguments key : ("+argsString + ")   ApplicationArguments value : ("+args.getOptionValues(argsString)+")");
        }
    }
}

第二个ApplicationRunner

package com.yxj.spring.runner;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:27
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:27
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 2)
public class MyApplicationRunner2 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        for(String argsString :args.getOptionNames()){
            System.out.println("order value is 2   。MyApplicationRunner2 is ApplicationArguments key : ("+argsString + ")   ApplicationArguments value : ("+args.getOptionValues(argsString)+")");
        }
    }
}

springBoot测试启动类

package com.yxj.spring;

import com.yxj.spring.Initializer.MyApplicationContextInitializer;
import com.yxj.spring.monitor.MyApplicationListener;
import com.yxj.spring.monitor.MyEvent;
import com.yxj.spring.properties.TestProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

import java.util.List;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/18 20:18
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/18 20:18
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@SpringBootApplication
public class SpringBootTestRun {

    @Value("${test.name}")
    private String testName;

    public static void main(String[] args) {
        SpringApplication springBootTestRun = new SpringApplication(SpringBootTestRun.class);
        ConfigurableApplicationContext run = springBootTestRun.run("测试1","测试2","--key1=测试3","--key2=测试4");
        run.close();
    }
}

测试结果

order value is 1   。MyCommandLineRunner2 run.  get args : [测试1, 测试2, --key1=测试3, --key2=测试4]
order value is 2   。MyApplicationRunner2 is ApplicationArguments key : (key1)   ApplicationArguments value : ([测试3])
order value is 2   。MyApplicationRunner2 is ApplicationArguments key : (key2)   ApplicationArguments value : ([测试4])
order value is 3   。MyApplicationRunner1 is ApplicationArguments key : (key1)   ApplicationArguments value : ([测试3])
order value is 3   。MyApplicationRunner1 is ApplicationArguments key : (key2)   ApplicationArguments value : ([测试4])
order value is 4   。MyCommandLineRunner1 run.  get args : [测试1, 测试2, --key1=测试3, --key2=测试4]
对比
  • 两个都是在容器启动成功后的最后一步回调
  • CommandLineRunner的参数是最原始的参数,没有做任何处理。ApplicationRunner的参数是ApplicationArguments,是对原始参数做了进一步的封装。
  • ApplicationRunner只对--key=value这种形式做解析,CommandLineRunner可以获得传递的所有字符串

本文分享自微信公众号 - 乱敲代码(gh_baf1250e9b02)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • springBoot学习(一)建立项目与读取配置文件

    Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用。

    乱敲代码
  • springBoot学习(二)配置环境动态切换和部分注解的运用

    建立第一个配置文件(springBoot默认读取的文件)application.properties

    乱敲代码
  • springBoot学习(三)springBoot事件监听和部分注解的运用

    1.springBoot启动类会使用@SpringBootApplication 2.点进入源代码发现改注解是一个复合注解,由好几个注解共同组合而成

    乱敲代码
  • Spring http服务远程调用实现过程解析

    最近公司有个新的需求,写了一个接口,想要把服务暴露出去,但是这个服务所在的进程是非web项目,(可以理解成schedule/batch等进程项目),所以没有to...

    砸漏
  • springBoot学习(四)项目初始化的开始和结束

    用来初始化Spring ConfigurableApplicationContext应用上下文的回调接口,是在ConfigurableApplicationCo...

    杨小杰
  • 【SpringCloud 】分布式配置中心

    在分布式系统中,每一个功能模块都能拆分成一个独立的服务,一次请求的完成,可能会调用很多个服务协调来完成,为了方便服务配置文件统一管理,更易于部署、维护,所以就需...

    林老师带你学编程
  • 《Spring Boot极简教程》第7章 Spring Boot集成模板引擎

    其实,没有任何一个模板引擎(jsp,velocity,thymeleaf,freemarker,etc)可以完全实现MVC绝对的分层,只有“自由度”上的界定罢了...

    一个会写诗的程序员
  • Spring Boot(十三)RabbitMQ安装与集成

    RabbitMQ是一个开源的消息代理软件(面向消息的中间件),它的核心作用就是创建消息队列,异步接收和发送消息,MQ的全程是:Message Queue中文的意...

    Java中文社群_老王
  • 对“利比亚天蝎”网络间谍活动的分析调查(附样本下载)

    利比亚的政权动荡和长期内战可能众所周知,但其网络间谍和黑客活动或许鲜为人知。在这篇报告中,我们将首次披露一例涉及利比亚的恶意软件网络攻击活动。 ? 概要 8月初...

    FB客服
  • C++创建People类--练习

    Enterprise_

扫码关注云+社区

领取腾讯云代金券