Spring Boot Application 事件和监听器
- 寻找到application.yml的读取的操作。
- 从spring.factories 中查看到
# Application Listeners
org.springframework.context.ApplicationListener = \
org.springframework.boot.context.config.ConfigFileApplicationListener, \
- ConfigFileApplicationListener 该对象对application.yml进行读取操作
- ConfigFileApplicationListener 事件的监听器, 继承了SmartApplicationListener接口
- SmartApplicationListener 接口继承了ApplicationListener 和 Ordered接口,能够实现有序监听。
一、SmartApplicationListener介绍
- Spring ApplicationEvent以及对应的Listener提供了一个事件监听、发布订阅的实现,内部实现方式是观察者模式,可以解耦业务系统之间的业务,提供系统的可拓展性、复用性以及可维护性。
- 在application.yml文件读取完会触发一个事件ConfigFileApplicationListener 该监听器实现文件的读取。
- SmartApplicationListener是高级监听器,是ApplicationListener的子类,能够实现有序监听
- SmartApplicationListener提供了两个方法:
/**
* 指定支持哪些类型的事件
*/
boolean supportsEventType( Class<? extends ApplicationEvent> var1 );
/**
* 指定支持发生事件所在的类型
*/
boolean supportsSourceType( Class<?> var1 );
如何在 SmartApplicationListener 实现监听解耦
- 1、我们只需在加载完成之后去加入一个监听器。
- 2、继承SmartApplicationListener接口
- 3、设置order属性决定监听器的顺序 ConfigFileApplicationListener.DEFAULT_ORDER + 1
- 4、将application.yml内容读取之后并修改
二、ConfigFileApplicationListener
- ConfigFileApplicationListener 是用来 读取配置文件的。 可以这样来粗略的介绍一下
- 详情可以请看 springboot启动时是如何加载配置文件application.yml文件
三、最终结果:
- 新增一个监听器 既然我们要在配置文件加载之后搞事情那么我们直接复制ConfigFileApplicationListener 的实现方式
- 删除一下不需要处理的操作(大概就是以下代码) 并且order在ConfigFileApplicationListener 之后
public class AfterConfigListener implements SmartApplicationListener, Ordered {
public boolean supportsEventType( Class<? extends ApplicationEvent> eventType )
{
return(ApplicationEnvironmentPreparedEvent.class.isAssignableFrom( eventType ) || ApplicationPreparedEvent.class.isAssignableFrom( eventType ) );
}
public void onApplicationEvent( ApplicationEvent event )
{
if ( event instanceof ApplicationEnvironmentPreparedEvent )
{
}
if ( event instanceof ApplicationPreparedEvent )
{
}
}
@Override
public int getOrder()
{
/* 写在加载配置文件之后 */
return(ConfigFileApplicationListener.DEFAULT_ORDER + 1);
}
}
- 这样子就完成了配置文件之后的代码监听。 SmartApplicationListener又是实现了ApplicationListener的监听的,那么我们可以在onApplicationEvent执行代码。
- 完善代码如下。 监听并且获取配置文件内容
public class AfterConfigListener implements SmartApplicationListener, Ordered {
/* 复制的ConfigFileApplicationListener文件内容 */
public boolean supportsEventType( Class<? extends ApplicationEvent> eventType )
{
return(ApplicationEnvironmentPreparedEvent.class.isAssignableFrom( eventType ) || ApplicationPreparedEvent.class.isAssignableFrom( eventType ) );
}
public void onApplicationEvent( ApplicationEvent event )
{
/* ApplicationEnvironmentPreparedEvent 是加载配置文件,初始化日志系统的事件。 */
if ( event instanceof ApplicationEnvironmentPreparedEvent )
{
/* 获得原来的password内容 */
String password = ( (ApplicationEnvironmentPreparedEvent) event).getEnvironment().getProperty( "spring.datasource.password" );
/* 进行密码的解密 */
System.setProperty( "spring.datasource.password", SM4Utils.encryptData_ECB( password ) );
}
if ( event instanceof ApplicationPreparedEvent )
{
}
}
@Override
public int getOrder()
{
/* 设置该监听器 在加载配置文件之后执行 */
return(ConfigFileApplicationListener.DEFAULT_ORDER + 1);
}
}
public class Application {
public static void main( String[] args )
{
SpringApplication springApplication = new SpringApplication( Application.class );
springApplication.addListeners( new AfterConfigListener() );
springApplication.run( args );
}
}