springboot 源码解析(2) - 监听器

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 的系统事件是 ApplicationEventAutoConfigurationImportEvent;所有我想和springboot 有关的事件应该都和这两货有关联
EventObject  继承图
一路跟下去,过程省略。。
Springboot 启动相关事件t
springboot 启动发送顺序

监听器注册

监听器的加载和初始化器 类似,这里不多描述,只挑出不同之处;不了解的看 springboot 自定义初始化器
启动类
加载监听器

监听器注册

触发机制(重点)

源码跟上:
启动类 run 方法
下面直接对着源码
SpringApplication
1 的源码:
SpringApplication
spring.factoies
2 的源码:
SpringApplicationRunListeners
EventPublishingRunListener
SimpleApplicationEventMulticaster
AbstractApplicationEventMulticaster
AbstractApplicationEventMulticaster
AbstractApplicationEventMulticaster
GenericApplicationListeneAdapter
上述两步;笔者认为只是为了拿到监听器感兴趣的监听事件
GenericApplicationListeneAdapter
剩下的代码不好截图了,要分不同类去判断,所以在这里进行口述:判断监听器是否属于 SmartApplicationListener ,如果属于则使用子类自己实现的 supportsEventType 方法;如果不是其子类,则判断是否是其监听的类型,看下面两个例子:
spring.factories
ConfigFileApplicationListener 实现 SmartApplicationListener 接口, 重写了 supportsEventType 方法,定义了监听事件 ApplicationEnvironmentPreparedEvent 和 ApplicationPreparedEvent
ConfigFileApplicationListener
ConfigFileApplicationListener
AnsiOutputApplicationListener 没有实现 SmartApplicationListener 接口,通过实现 ApplicationListener接口, 泛型标识要监听的事件
AnsiOutputApplicationListener
重点结束了,接下来回到 AbstractApplicationEventMulticaster 中,加入缓存中AbstractApplicationEventMulticaster
SimpleApplicationEventMulticaster
大概流程图(从网上找来的)
流程图
以上所有截图都是表述 springboot 启动时候的监听 starting 事件,还有其他事件,都是大同小异,这里不错描述了
SprignApplication
这里关于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..");
    }
}

console

以上三种方式都是针对单个事件监听的,如果想针对多个事件监听该怎么办呢?

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);
    }

console
简单来说:这种方式算是对事件监听的一种扩展

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值