【Java基础系列2】事件注解@EventListener使用姿势

简介: 借助Spring可以非常简单的实现事件监听机制,本文简单介绍下面向接口与注解@EventListener监听的两种姿势。

H0QSL}JK%SJ_2WZDER1)HJ0.png

借助Spring可以非常简单的实现事件监听机制,本文简单介绍下面向接口与注解@EventListener监听的两种姿势。


事件示例


事件对象

在Spring中,所有的事件需要继承自ApplicationEvent,一个最基础的MsgEvent如下

public class MsgEvent extends ApplicationEvent {
    private String msg;
    /**
     * Create a new {@code ApplicationEvent}.
     *
     * @param source the object on which the event initially occurred or with
     *               which the event is associated (never {@code null})
     */
    public MsgEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }
    @Override
    public String toString() {
        return "MsgEvent{" +
                "msg='" + msg + '\'' +
                '}';
    }
}


接口方式消费

消费事件有两种方式,接口的声明,主要是实现ApplicationListener接口;注意需要将listener声明为Spring的bean对象

@Service
public class MsgEventListener implements ApplicationListener<MsgEvent> {
    @Override
    public void onApplicationEvent(MsgEvent event) {
        System.out.println("receive msg event: " + event);
    }
}


注解方式消费

实现接口需要新建实现类,更简单的方法是直接在消费方法上加一个注解@EventListener

@EventListener(MsgEvent.class)
public void consumer(MsgEvent msgEvent) {
    System.out.println("receive msg event by @anno: " + msgEvent);
}

这个注解,支持根据Event参数类型进行匹配,即上面的实例中,方法上直接加@EventListener不指定圆括号内部的也没关系


发布事件

前面是消费事件,消费的前提是有事件产生,在Spring中,发布事件主要需要借助ApplicationContext来实现

@Service
@ComponentScan({"com.java.event"})
public class MsgPublisher implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    // 发起事件通知
    public void publish(String msg) {
        applicationContext.publishEvent(new MsgEvent(this, msg));
    }
    // 通过注解的方法
    @EventListener(MsgEvent.class)
    public void consumer(MsgEvent msgEvent) {
        System.out.println("receive msg event by @anno: " + msgEvent);
    }
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MsgPublisher.class);
        MsgPublisher msgPublisher = context.getBean(MsgPublisher.class);
        msgPublisher.publish("louzai");
    }
}

说明:

  • @ComponentScan用于扫描Spring的Bean;
  • 我把“注解方式消费”直接作为MsgPublisher的方法,主要是为了偷懒,你也可以单独整个类,然后将consumer()作为类的成员方法;
  • main()是用于测试,直接通过ApplicationContext拿到MsgPublisher的Bean。


测试

直接执行MsgPublisher的main(),输出结果如下:

receive msg event by @anno: MsgEvent{msg='louzai'}
receive msg event: MsgEvent{msg='louzai'}


后记


因为明天开发要用这个,所以就看了一下同事写的一篇博文,然后简单跑了一下。

最近很少写文章,不是懒,是因为这两周在决策一件非常重要的事情,等结果出来了,再告诉大家。等这件事情尘埃落定后,我还是会继续每周输出1-2篇文章。

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
1月前
|
Java Spring 容器
【Java】Spring如何扫描自定义的注解?
【Java】Spring如何扫描自定义的注解?
35 0
|
30天前
|
Java 数据库连接
hibernate注解实体类(Dept.java)
hibernate注解实体类(Dept.java)
13 1
|
3月前
|
缓存 安全 Java
Java学习—注解与反射2(狂神说超详细版)
Java学习—注解与反射(狂神说超详细版)
Java学习—注解与反射2(狂神说超详细版)
|
3月前
|
Java 程序员 编译器
Java学习—注解与反射1(狂神说超详细版)
Java学习—注解与反射(狂神说超详细版)
|
30天前
|
Java 数据库连接
Hibernate中使用Criteria查询及注解——(Dept.java)
Hibernate中使用Criteria查询及注解——(Dept.java)
14 1
|
26天前
|
存储 SQL Java
【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了(二)
【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了
44 1
|
1天前
|
Java 测试技术 编译器
JAVA注解
JAVA注解
8 0
|
22天前
|
搜索推荐 Java
Java基础(快速排序算法)
Java基础(快速排序算法)
23 4
|
30天前
|
Java 数据库连接
hibernate注解实体类(Emp.java)
hibernate注解实体类(Emp.java)
14 1
|
30天前
|
Java 数据库连接
Hibernate中使用Criteria查询及注解——(DeptTest.java)
Hibernate中使用Criteria查询及注解——(DeptTest.java)
8 1