文章目录
Springboot 监听器 成员
系统监听器 ApplicationListener
JDK 监听器声明接口 EventListener
/**
* A tagging interface that all event listener interfaces must extend.
* jdk 的接口;用于监听器声明;继承这个接口的子接口都基于监听器标准
*/
public interface EventListener {
}
ApplicationListener
//注解@FunctionalInterface表明系统监听器可实现函数式编程
@FunctionalInterface
//<E extends ApplicationEvent> 用于声明对哪些事件感兴趣
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
//处理监听到的事件
void onApplicationEvent(E event);
}
系统广播器 ApplicationEventMulticaster
public interface ApplicationEventMulticaster {
//添加监听器
void addApplicationListener(ApplicationListener<?> listener);
//添加监听器
void addApplicationListenerBean(String listenerBeanName);
//移除监听器
void removeApplicationListener(ApplicationListener<?> listener);
//移除监听器
void removeApplicationListenerBean(String listenerBeanName);
//移除所有监听器
void removeAllListeners();
//广播事件
void multicastEvent(ApplicationEvent event);
//广播事件
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
系统事件
JDK 事件声明类 EventObject
public class EventObject implements java.io.Serializable {
protected transient Object source;
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
}
通过继承关系图发现 springboot 的系统事件是 ApplicationEvent 和 AutoConfigurationImportEvent;所有我想和springboot 有关的事件应该都和这两货有关联
一路跟下去,过程省略。。
监听器注册
监听器的加载和初始化器 类似,这里不多描述,只挑出不同之处;不了解的看 springboot 自定义初始化器
触发机制(重点)
源码跟上:
1 的源码:
2 的源码:
上述两步;笔者认为只是为了拿到监听器感兴趣的监听事件
剩下的代码不好截图了,要分不同类去判断,所以在这里进行口述:判断监听器是否属于 SmartApplicationListener ,如果属于则使用子类自己实现的 supportsEventType 方法;如果不是其子类,则判断是否是其监听的类型,看下面两个例子:
ConfigFileApplicationListener 实现 SmartApplicationListener 接口, 重写了 supportsEventType 方法,定义了监听事件 ApplicationEnvironmentPreparedEvent 和 ApplicationPreparedEvent
AnsiOutputApplicationListener 没有实现 SmartApplicationListener 接口,通过实现 ApplicationListener接口, 泛型标识要监听的事件
重点结束了,接下来回到 AbstractApplicationEventMulticaster 中,加入缓存中
大概流程图(从网上找来的)
以上所有截图都是表述 springboot 启动时候的监听 starting 事件,还有其他事件,都是大同小异,这里不错描述了
这里关于Springboot 启动时候自带监听器源码就理解到这,可是这些监听器有的时候并不满足我们自己的业务需求,那就需要我们自定义监听器
自定义监听器
第一种方式
使用spring.factories 配置文件
org.springframework.context.ApplicationListener=com.king.netty.boot.listener.div.FirstListener
public class FirstListener implements ApplicationListener<ApplicationContextInitializedEvent> {
@Override
public void onApplicationEvent(ApplicationContextInitializedEvent event) {
System.out.println("first listener..");
}
}
第二种方式
手动添加
public class SecondListener implements ApplicationListener<ApplicationContextInitializedEvent> {
@Override
public void onApplicationEvent(ApplicationContextInitializedEvent event) {
System.out.println("second listener..");
}
}
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(NettyTestApplication.class);
springApplication.addListeners(new SecondListener());
springApplication.run(args);
}
第三种方式
使用 application.properties 配置文件
## 添加监听器
context.listener.classes=com.king.netty.boot.listener.div.ThirdListener
public class ThirdListener implements ApplicationListener<ApplicationContextInitializedEvent> {
@Override
public void onApplicationEvent(ApplicationContextInitializedEvent event) {
System.out.println("third listener..");
}
}
以上三种方式都是针对单个事件监听的,如果想针对多个事件监听该怎么办呢?
public class FouthListener implements SmartApplicationListener {
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
//支持多种事件
return eventType.isAssignableFrom(ApplicationContextInitializedEvent.class) || eventType.isAssignableFrom(ApplicationStartedEvent.class);
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("fourth listener..");
}
}
写好之后,使用上面三种方式随便其中一个注入下即可
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(NettyTestApplication.class);
springApplication.addListeners(new SecondListener());
springApplication.addListeners(new FouthListener());
springApplication.run(args);
}
简单来说:这种方式算是对事件监听的一种扩展