java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring事件监听机制ApplicationEvent

Spring事件监听机制ApplicationEvent方式

作者:爱琴孩

这篇文章主要介绍了Spring事件监听机制ApplicationEvent方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

前言

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

ApplicationEvent的小demo

ApplicationEvent本身是抽象类,无法直接实例化。一般通过子类继承ApplicationEvent

public class MyApplicationEvent extends ApplicationEvent {
    private Student student;
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public MyApplicationEvent(Object source) {
        super(source);
    }
    public MyApplicationEvent(Object source, Student student) {
        super(source);
        this.student = student;
    }
}

事件定义好之后,我们注册个事件监听器即可。

实现ApplicationListener接口注册监听器

@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyApplicationListener.class);
    @Override
    public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
        Student student = myApplicationEvent.getStudent();
        LOGGER.info("学生对象是={}", JSONObject.toJSONString(student));
    }
}

通过@EventListener注册监听器,ApplicationContext.publishEvent 默认是同步操作, 并非发布后不管的异步操作,发布事件后需要等 @EventListener 执行完。

如果需要开启异步操作 需要在 @EventListener 上 增加 @Async 注解。

@Component
public class AsyncApplicationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncApplicationListener.class);
    @EventListener
    @Async
    public void listener(MyApplicationEvent myApplicationEvent) {
        Student student = myApplicationEvent.getStudent();
        LOGGER.info("通过@EventListener获取学生对象信息={}", JSONObject.toJSONString(student));
    }
}

通过实现SmartApplicationListener接口注册监听器

SmartApplicationListener接口继承了全局监听ApplicationListener,并且泛型对象使用的ApplicationEvent来作为全局监听,可以理解为使用SmartApplicationListener作为监听父接口的实现,监听所有事件发布。

既然是监听所有的事件发布,那么SmartApplicationListener接口添加了两个方法supportsEventType、supportsSourceType来作为区分是否是我们监听的事件,只有这两个方法同时返回true时才会执行onApplicationEvent方法。

@Component
public class MySmartApplicationListener implements SmartApplicationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(MySmartApplicationListener.class);
    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) {
        return aClass == MyApplicationEvent.class;
    }
    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return sourceType == ApplicationRunnerTest.class;
    }
    @Override
    public int getOrder() {
        return 0;
    }
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        MyApplicationEvent myApplicationEvent = (MyApplicationEvent) applicationEvent;
        LOGGER.info("通过MySmartApplicationListener 获取学生对象信息={}",
                JSONObject.toJSONString(myApplicationEvent.getStudent()));
    }
}

可以看到除了上面的方法,还提供了一个getOrder方法,这个方法就可以解决执行监听的顺序问题,return的数值越小证明优先级越高,执行顺序越靠前

发布事件

在Spring的Bean中,注入ApplicationContext ,通过ApplicationContext 来进行事件发布

@Autowired
private ApplicationContext applicationContext;
applicationContext.publishEvent(new MyApplicationEvent(this, new Student("爱琴孩", 18)));

运行结果

2023-01-28 10:38:39.696 YYZX_Study 13540 [           main]  INFO c.e.s.s.MySmartApplicationListener          37: 通过MySmartApplicationListener 获取学生对象信息={"age":18,"name":"爱琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [           main]  INFO c.e.study.service.MyApplicationListener     22: 学生对象是={"age":18,"name":"爱琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [tOrderService-1]  INFO c.e.s.service.AsyncApplicationListener      25: 通过@EventListener获取学生对象信息={"age":18,"name":"爱琴孩"}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文