SpringBoot 实现事件发布和监听主要用到的类ApplicationEventPublisher、ApplicationEvent,当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法。
实现步骤:
1、定义事件类
事件是一个自定义的类,需要继承Spring提供的ApplicationEvent
。
import com.alibaba.fastjson.JSONObject;
import org.springframework.context.ApplicationEvent;
/**
* 自定义 事件类
*/
public class EsSaveEvent extends ApplicationEvent {
private JSONObject data;
public EsSaveEvent(JSONObject source) {
super(source);
this.data = source;
}
public JSONObject getData() {
return data;
}
}
2、定义监听器
方式1:自定义监听器
自定义一个监听器 implements ApplicationListener
接口,实现onApplicationEvent()
方法,然后添加到ApplicationContext
。
import org.springframework.context.ApplicationListener;
public class MyListener implements ApplicationListener {
@Override
public void onApplicationEvent(EsSaveEvent event) {
//事件处理
System.out.print("监听到MyEvent事件");
}
}
注意:需要在springboot 启动类添加监听器,如下所示:
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
SpringBoot的启动类中添加监听器
application.addListeners(new MyListener());
application.run(args);
}
方式2:使用注解@EventListener
(推荐)
原理就是通过扫描这个注解,创建监听器并添加到ApplicationContext
。
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
/**
* @Title: EventListener
*/
@Component
public class EventListener {
//监听事件
@org.springframework.context.event.EventListener
public void listenEvent(EsSaveEvent event) {
//可以添加事务处理
//divide(event);
JSONObject object = event.getData();
//对数据进行处理
System.out.println("data:"+object.toJSONString());
}
}
//在监听器中重新开一个事务(可选)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void divide(EsSaveEvent event) {
System.out.println("事务处理");
}
}
3、发布事件
事件发布可以用springboot内部类 也可以自定义
方式1:直接注入 ApplicationEventPublisher
使用 ApplicationEventPublisher,注入ApplicationEventPublisher接口,调用publisher.publishEvent(new EsSaveEvent(data)) 发布事件。
@Autowired
private ApplicationEventPublisher publisher;
public test(){
JSONObject data=new JSONObject();
publisher.publishEvent(new EsSaveEvent(data));
}
方式2:自定义事件发布类(继承ApplicationEventPublisher)
实现 ApplicationEventPublisher
import com.alibaba.fastjson.JSONObject;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
@Component
public class EventService implements ApplicationEventPublisherAware {
public ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
public String doEventWork(String msg) {
JSONObject data=new JSONObject();
data.put("message","------------publish event:" + msg);
EsSaveEvent event = new EsSaveEvent(data);
publisher.publishEvent(event);
return "OK";
}
}
测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class EventServiceTest {
@Autowired
private EventService service;
@Test
public void eventTest() {
String msg="Java Code";
service.doEventWork(msg);
}
}
注意事项
1、如果2个事件之间是继承关系,会先监听到子类事件,处理完再监听父类。
2、监听器方法一定要try-catchy异常,否则会造成发布事件(有事务的)的方法进行回滚
3、可以使用@Order注解控制多个监听器的执行顺序,@Order 传入的值越小,执行顺序越高