龙空技术网

SpringBoot进阶-SpringBoot中如何配置动态刷新操作?

幽默的程序员面试宝典 1775

前言:

当前咱们对“springboot动态配置”大约比较着重,姐妹们都想要学习一些“springboot动态配置”的相关内容。那么小编在网络上收集了一些有关“springboot动态配置””的相关文章,希望各位老铁们能喜欢,你们一起来了解一下吧!

在实际工作开发中,我们经常会遇到在项目启动的时候对应用进行一些初始化的操作,例如对于线程池的初始化、对于证书的初始化等等操作。那么在面试的时候面试官也会问到在SpringBoot中的动态加载配置相关的内容,那么下面我们就来看看在Spring Boot中对于配置动态刷新常用的几种方式。

第一、通过监听容器刷新完扩展点

我们知道在Spring ApplicationContext中提供了基于观察者模式的事件处理机制,通过ApplicationEvent 和ApplicationListener两个接口来实现ApplicationContext的事件机制,当然在Spring中也提供了一些内置的事件机制。

ContextRefreshedEvent: ApplicationContext被初始化或者发生刷新操作的时候,这个事件就会被触发,当然也可以在ConfigurableApplicationContext接口中使用refresh()方法来触发。当然这里需要注意的一点是这里所指的初始化是当所有的Bean对象都被成功装载,后处理Bean被检测并且激活,所有的Singleton Bean都被预实例化,这个时候ApplicationContext容器就可以就绪使用了。

ContextStartedEvent:当使用ConfigurationApplicationContext 接口中的start方法启动ApplicationContext的时候,该事件被触发。

ContextStoppedEvent:当使用ConfigurationApplicationContext 接口中的stop方法停止ApplicationContext的时候,该事件被触发。

ContextCloseEvent:当使用ConfigurationApplicationContext 接口的close方法关闭ApplicationContext的时候,该事件被触发。

RequesthandledEvent:这是一个web-specific事件,用来告知Bean Http请求已经被服务。只能应用于使用DispatcherServlet的Web应用。在使用Spring 作为前端的MVC控制器的时候,当Spring处理用户请求结束之后,系统自动触发该事件。

可以做个简单的小测试。启动Spring Boot之后会看到事件内容被打印了。

@Componentpublic class TestApplicationListener implements   ApplicationListener<ContextRefreshedEvent> {    @Override    public void onApplicationEvent(ContextRefreshedEvent event) {        System.out.println("触发了ContextRefreshedEvent事件");    }}
第二、使用Spring Boot的CommandLineRunner接口

在Spring容器被初始化之后会调用CommandLineRunner接口中的run方法,同样通过这种方式也可以实现动态参数传递,而且这种方式要比通过ApplicationListener的方式相对灵活。如下

@Componentpublic class TestCommandLineRunner implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        System.out.println(Arrays.asList(args));    }}

可以在项目启动的时候通过命令行传入参数

第三、通过Spring Boot的ApplicationRunner接口

ApplicationRunner和CommandLineRunner都是Spring Boot提供的接口,相对于CommandLineRunner来说对控制台传入的参数封装的相对友好一些,可以通过键值对的方式来进行参数的传递。

@Componentpublic class TestApplicationRunner implements ApplicationRunner {    @Override    public void run(ApplicationArguments args) throws Exception {        System.out.println(args.getOptionNames());        System.out.println(args.getNonOptionArgs());        System.out.println(args.getSourceArgs());    }}

可以采用同样的方式进行参数的传入测试。

第四、使用@PostConstruct 注解

前面三种方式都是通过容器初始化完成之后做的事情,而@PostConstruct 注解则是针对Bean初始化完成之后来做一些事情,例如对于一些监听器的注册、对于一些初始化对象调用。

@PostConstruct 注解一般都是放在Bean的方法上,一旦Bean对象被初始化了,就会调用这个方法对方法中的的内容进行调用。

@Componentpublic class TestBean {    @PostConstruct    public void init(){        System.out.println("Bean对象被初始化了");    }}

从代码执行的结果来看,Bean对象初始化的调用要比容器初始化的调用要早,这是由于容器要等待所有的Bean都被加载才能算是初始化完成,这个在前面的内容中我们介绍过。

第五、使用@Bean注解的指定的初始化方法

在使用XML配置文件的时候我们用到过一个init-method的属性,这个属性就是用来指定加载Bean完成之后调用那个方法这里,我们也是通过注解版的这个属性来实现这个操作,整个的操作的过程与@PostConstruct注解类似。

首先需要定义一个测试Bean对象

public class TestInitBean {    public void init(){        System.out.println("使用Bean注解的InitMethod属性");    }}

定义配置文件来注入Bean对象,并且指定初始化方法。

@Configurationpublic class TestConfig {    @Bean(initMethod = "init")    public TestInitBean testInitBean(){        return new TestInitBean();    }}
第六、使用InitializingBean接口

InitializingBean的基本用法与@PostConstruct 注解的用法类似,不过就是需要实现afterPropertiesSet()方法,具有一定的代码侵入性。

@Componentpublic class InitImplTestBean implements InitializingBean {    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("Bean初始化完成");    }}
总结

通过上面的几种方式,我们可以实现动态配置的加载,当然可以实现动态配置加载的方式还有很多不仅局限于这种方式,希望有兴趣的读者多多留意。

标签: #springboot动态配置