SpringBoot事件监听和发布

SpringBoot 实现事件发布和监听主要用到的类ApplicationEventPublisher、ApplicationEvent,当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法。

实现步骤:

  • 自定义发布的事件类,需要继承 ApplicationEvent 或者PayloadApplicationEvent(该类也仅仅是对ApplicationEvent的一层封装)
  • 监听事件 使用注解 @EventListener 或者 自定义监听器在主函数添加监听器
  • 使用ApplicationEventPublisher 或者 实现其接口的子类 发布自定义事件 (@Autowired注入即可)

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 传入的值越小,执行顺序越高

你可能感兴趣的:(#,spring,boot,spring,java)