spring 之 Event

一、什么是Event

ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。

二、Event

2.1、event的类型

在这里插入图片描述

2.2、context相关

序号内置事件解释
1ContextRefreshedEventApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext 接口中使用 refresh() 方法来发生。
2ContextStartedEvent当使用 ConfigurableApplicationContext 接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序
3ContextStoppedEvent当使用 ConfigurableApplicationContext 接口中的 stop() 方法停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作
4ContextClosedEvent当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启

2.3、Spring boot相关

序号内置事件解释
1ApplicationStartingEvent在Spring最开始启动的时候触发
2ApplicationEnvironmentPreparedEvent在Spring已经准备好环境但是上下文尚未创建的时候触发
3ApplicationContextInitializedEvent在spring 创建和初始化好上下文,在 bean 的定义(bean definitions)被加载之前发送
4ApplicationPreparedEvent这个事件是在 Spring 上下文(context)刷新之前,且在 bean 的定义(bean definitions)被加载之后发送。
5ApplicationStartedEvent这个事件是在 Spring 上下文(context)刷新之后,且在 application/ command-line runners 被调用之前发送。
6ApplicationReadyEvent这个事件在任何 application/ command-line runners 调用之后发送
7ApplicationFailedEvent这个事件在应用启动异常时进行发送。

三、EventListener

3.1、新建监听器

ApplicationListener

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
	void onApplicationEvent(E event);
}
public class BootDataSourceAutoConfiguration
    implements ApplicationListener<ApplicationEnvironmentPreparedEvent>
{
    private static DateTimeFormatter staticLocalDateTimeFormat;
    private static DateTimeFormatter staticLocalTimeFormat;
    
    public void onApplicationEvent(@NonNull ApplicationEnvironmentPreparedEvent event) {
        ConfigurableEnvironment configurableEnvironment = event.getEnvironment();
        if (null == staticLocalDateTimeFormat) {
            String localDateTimeFormat = configurableEnvironment.resolvePlaceholders("${c2f.application.datasource.local-date-time.format:yyyy-MM-dd HH:mm:ss}");
            
            staticLocalDateTimeFormat = DateTimeFormatter.ofPattern(localDateTimeFormat);
        } 
        if (null == staticLocalTimeFormat) {
            String localTimeFormat = configurableEnvironment.resolvePlaceholders("${c2f.application.datasource.local-time.format:HH:mm:ss}");
            
            staticLocalTimeFormat = DateTimeFormatter.ofPattern(localTimeFormat);
        } 
    }
 }

使用@EventListener

public class MsgEvent extends ApplicationEvent {
    private String msg;
    public MsgEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "MsgEvent{" +
                "msg='" + msg + '\'' +
                '}';
    }
}
@EventListener(MsgEvent.class)
public void consumer(MsgEvent msgEvent) {
    System.out.println("receive msg event by @anno: " + msgEvent);
}

3.2、EventListener注册

1、在资源目录中的 META-INF/spring.factories 文件中自动注册:

org.springframework.context.ApplicationListener=\ cn.javastack.springboot.features.listener.JavastackListener

2、如果是监听 Spring 应用上下文(ApplicationContext)创建之后的事件,可以直接在监听器上使用 @Component 注解即可,否则需要使用第一种方法的自动注册,因为 ApplicationContext 并未创建,这时的 Bean 是不能被加载的。

四、ApplicationEventMulticaster管理

用来向ApplicationListener广播消息
在这里插入图片描述

/**
     * 添加监听器,用来接收所有事件的通知
     */
    void addApplicationListener(ApplicationListener<?> listener);

    /**
     * 根据Bean名称添加监听器
     */
    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);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值