spring的自定义事件使用


最近看到博文有提到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点也是可以的,就是后面接手的人很容易疯,呵呵。

你可能感兴趣的:(springboot)