序
最近看到博文有提到spring事件监听的,看完其实感觉这个事件跟aop的功能一样,为了业务解耦,方便改动。跟异步又也很像,可以不用管执行结果。当然如果是要求执行成功的,也没必要用,费劲写半天还不如直接在方法里写。废话也不多说,直接上spring事件的使用,至于什么场景用,就看大家的了。
一、自定义事件类
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* @author zhengwen
**/
@Data
public class MyEvent {
/**
* 对象主键
*/
private Long id;
/**
* 事件英文名称
*/
private String enName;
/**
* 事件中文名称
*/
private String cnName;
/**
* 对象json
*/
private JSONObject modelJson;
public MyEvent(Long id, String enName, String cnName, JSONObject modelJson) {
this.id = id;
this.enName = enName;
this.cnName = cnName;
this.modelJson = modelJson;
}
}
这里主要是考虑一个是业务对象的主键、事件的中、英文名称、业务对象jsonObject对象(方便根据业务对象参数写逻辑)
二、监听器
import com.fillersmart.tgsaas.data.constant.BusinessConstant;
import com.fillersmart.tgsaas.data.core.RedisUtil;
import com.fillersmart.tgsaas.data.util.redis.RedisConstant;
import com.fillersmart.tgsaas.deviceservice.event.MyEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* @author zhengwen
**/
@Slf4j
@Component
public class MyEventLintener {
@Autowired
private RedisUtil redisUtil;
/**
* 自定义事件监听处理
* 使用@Async实现异步监听,不要异步可以去掉
* @param myEvent
*/
@Async
@EventListener(condition = "#myEvent.enName=='saveDevice'")
public void myEventHandle(MyEvent myEvent) {
log.info("-------in---------");
String saveEvent = redisUtil.getString(RedisConstant.PREFIX + "event:saveDevice");
if (BusinessConstant.EVENT_LISTEN_ON.getType().equals(saveEvent)){
log.info("-------保存设备事件监听打开---------");
log.info("发布的data为:{}", myEvent.toString());
}else {
log.info("----保存设备事件监听关闭------");
}
}
}
之前说过,如果是同步可以不用这么麻烦,但是要想麻烦也可以,就是不要@Async注解标签就行。然后EventListener(condition = “#myEvent.enName==‘saveDevice’”)这个注解标签就是执行方法上要增加的(我一直强调我也是个怕麻烦的人,所以直接用注解标签,其实还有一种实现方式是面向接口的)后面的condition是对事件的过滤,不然所以spring的事件都会进这个方法(影响性能)。
我这里为了能随时插拔监听,使用redis记录事件开关。
三、事件发布
service实现类里注入ApplicationEventPublisher,方法里publishEvent。
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override
public Result<?> save(DeviceInfoVo deviceInfoVo) {
//TODO保存deviceInfo
//自定义事件发布
MyEvent myEvent = new MyEvent(deviceInfo.getId(),"saveDevice","设备保存", (JSONObject) JSON.toJSON(deviceInfo));
eventPublisher.publishEvent(myEvent);
return ResultGenerator.genSuccessResult();
}
四、总结
1、spring的事件要适量使用
2、spring的事件千万不要嵌套使用,否则业务会非常复杂
其他的其实也没什么,其实不做到上面2点也是可以的,就是后面接手的人很容易疯,呵呵。