spring事件驱动用于单体架构解耦时很好的方式,下面看如何使用
首先创建事件基类BaseEvent.java,内容如下:
package org.demo.event;
import org.springframework.context.ApplicationEvent;
import java.lang.reflect.Constructor;
import java.util.UUID;
/**
* 事件驱动基类Event
*/
public class BaseEvent<T> extends ApplicationEvent{
private String eventId;
private T body;
public BaseEvent(Object source, T body) {
super(source);
this.eventId = UUID.randomUUID().toString().replace("-","");
this.body = body;
}
public String getEventId() {
return eventId;
}
public T getBody() {
return body;
}
public static <P extends BaseEvent<T>,T>P builder(Class<P> clazz, Object source, T body) {
try {
Constructor<P> constructor = clazz.getConstructor(Object.class, body.getClass());
return constructor.newInstance(source, body);
} catch (Exception e) {
throw new RuntimeException("BaseEvent Failed to create instance of " + clazz.getName(), e);
}
}
}
继续创建事件监听基类BaseEventListener.java,内容如下:
package org.demo.event.listener;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.demo.event.BaseEvent;
import org.springframework.context.ApplicationListener;
/**
* 事件监听基类EventListener
*/
@Slf4j
public abstract class BaseEventListener<T extends BaseEvent<P>,P> implements ApplicationListener<T> {
@Override
public void onApplicationEvent(T event) {
String simpleName = event.getClass().getSimpleName();
log.info("Event:{} start.",simpleName);
log.info("Event:{}[eventId:{}]",simpleName,event.getEventId());
long startTime = System.currentTimeMillis();
try {
if (!preProcess(event)) {
return;
}
if (this.execute(event.getBody(),event)){
log.info("Event success[eventId:{}],body:{}",event.getEventId(),JSON.toJSONString(event.getBody()));
}else {
this.failHandler(event);
}
} catch (Exception e) {
this.exceptionHandler(event,e);
}
long time = System.currentTimeMillis() - startTime;
log.info("Event:{}[eventId:{}] end. {}ms",simpleName,event.getEventId(),time);
}
/**
* 事件异常(可重写)
* @param event
* @param e
*/
protected void exceptionHandler(T event,Exception e){
log.info("Event exception[eventId:{}],body:{},{}",event.getEventId(),JSON.toJSONString(event.getBody()),e);
}
/**
* 事件失败(可重写)
* @param event
*/
protected void failHandler(T event){
log.info("Event fail[eventId:{}],body:{}",event.getEventId(),JSON.toJSONString(event.getBody()));
}
/**
* 事件前置处理(可重写)
* @param event
* @return
*/
protected boolean preProcess(T event) {
if (event.getEventId() == null || event.getBody() == null) {
log.info("Event unknown error,Event:{}[eventId:{}]", event.getClass().getSimpleName(),event.getEventId());
return Boolean.FALSE;
}
if (!isCheck(event.getBody(),event)) {
log.info("Event body verify,[eventId:{}],body:{} ", event.getEventId(),JSON.toJSONString(event.getBody()));
return Boolean.FALSE;
}
return Boolean.TRUE;
}
/**
* 是否校验(可重写)
* @param body
* @param event
* @return
*/
protected boolean isCheck(P body,T event) {
return true;
}
/**
* 执行逻辑(必须实现)
* @param body
* @param event
* @return
*/
protected abstract boolean execute(P body, T event);
}
接着创建一个事件发布的工具类EventPubUtil.java,内容如下:
package org.demo.event.util;
import lombok.extern.slf4j.Slf4j;
import org.demo.event.BaseEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
/**
* 事件发布工具
*/
@Slf4j
@Component
public class EventPubUtil {
private static ApplicationEventPublisher applicationEventPusher;
@Autowired
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
EventPubUtil.applicationEventPusher = applicationEventPublisher;
}
/**
* 发布事件
* @param event
*/
public static <T>void publish(BaseEvent<T> event) {
log.info("publish event:{}",event.getClass().getSimpleName());
applicationEventPusher.publishEvent(event);
}
}
到此基本完成,接下来就是写测试测试一下,创建测试实体对象pojoTestPojo.java,内容如下:
package org.demo.event.pojo;
import lombok.Data;
@Data
public class TestPojo {
private String name;
private Integer age;
}
继续创建测试事件TestEvent.java,内容如下:
package org.demo.event;
import org.demo.event.pojo.TestPojo;
/**
* 测试事件
*/
public class TestEvent extends BaseEvent<TestPojo>{
public TestEvent(Object source, TestPojo testPojo){
super(source, testPojo);
}
}
继续创建测试事件监听TestEventListener.java,内容如下:
package org.demo.event.listener;
import com.alibaba.fastjson.JSON;
import org.demo.event.TestEvent;
import org.demo.event.pojo.TestPojo;
import org.springframework.stereotype.Component;
/**
* 测试事件监听
*/
@Component
public class TestEventListener extends BaseEventListener<TestEvent, TestPojo> {
@Override
public boolean execute(TestPojo body, TestEvent event) {
System.out.println("TestEventListener execute:body="+ JSON.toJSONString( body));
return true;
}
}
接下来就是创建一个接口发布一下测试事件,内容如下:
@GetMapping("/event")
public String event() {
TestPojo testPojo = new TestPojo();
testPojo.setName("测试一下");
testPojo.setAge(18);
TestEvent builder = TestEvent.builder(TestEvent.class, this, testPojo);
EventPubUtil.publish(builder);
return "event";
}
到此完成,访问一下接口,可以看到控制台事件监听打印了。