SpringBoot 异步事件实现异步(ApplicationEventPublisher、ApplicationEvent)

1 篇文章 0 订阅
1 篇文章 0 订阅

SpringBoot 异步事件实现异步(ApplicationEventPublisher、ApplicationEvent)

​ 当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法。

实现步骤:

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

一、事件本身 ApplicationEvent

事件是一个自定义的类,需要继承Spring提供的ApplicationEvent

import com.alibaba.fastjson.JSONObject;
import org.springframework.context.ApplicationEvent;

/**
 * 自定义 事件
 * @author 王泽华
 * 2019/10/22 14:59
 */
public class EsSaveEvent extends ApplicationEvent {

    private JSONObject data;

    public EsSaveEvent(JSONObject source) {
        super(source);
        this.data = source;
    }

    public JSONObject getData() {
        return data;
    }
}

二、事件监听

1、自定义监听器

​ 基本方法是实现ApplicationListener接口,自定义一个监听器,实现onApplicationEvent()方法,然后添加到ApplicationContext

import org.springframework.context.ApplicationListener;

public class MyListener implements ApplicationListener<EsSaveEvent> {

    @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;

/**
 * @author :王泽华
 * @Title: EventListener
 * @date 2019/10/2214:18
 */
@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("事务处理");
    }


}

三、事件发布

事件发布可以用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)

A、实现 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";
    }
}

B、测试

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

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值