当前热讯:Spring ApplicationEvent事件实现本地事件驱动

2023-05-06 21:27:22 来源:清一色财经

TransactionalEventListener,事务事件监听,可监听事务提交前、提交后、事务回滚、事务完成(成功或失败)。


(资料图片)

一、介绍

Spring内置了简便的事件机制,可以非常方便的实现事件驱动,核心类包括

ApplicationEvent,具体事件内容,事件抽象基类,可继承该类自定义具体事件ApplicationEventPublisher,事件发布器,可以发布ApplicationEvent,也可以发布普通的Object对象ApplicationListener,事件监听器,可以使用注解@EventListenerTransactionalEventListener,事务事件监听,可监听事务提交前、提交后、事务回滚、事务完成(成功或失败)

二、使用示例:不定义事件,直接发布Object对象,同步

1、定义发送事件对象

public class UserEntity {    private long id;    private String name;    private String msg;}

2、定义事件监听器

可以添加条件condition,限制监听具体的事件

@Slf4j@Componentpublic class RegisterListener {    @EventListener(condition = "#entity.id != null and #entity.async==false ")    public void handlerEvent(UserEntity entity) {        try {            // 休眠5秒            TimeUnit.SECONDS.sleep(5);        } catch (InterruptedException e) {            e.printStackTrace();        }        log.info("handlerEvent: {}", entity);    }}

3、定义发送接口以及实现类

public interface IRegisterService {    public void register(String name);}
@Servicepublic class RegisterServiceImpl implements IRegisterService {    @Resource    private ApplicationEventPublisher applicationEventPublisher;    @Override    public void register(String name) {        UserEntity entity = new UserEntity();        entity.setName(name);        entity.setId(1L);        entity.setMsg("新用户注册同步调用");        applicationEventPublisher.publishEvent(entity);    }}

4、测试Controller类,进行测试

@Slf4j@Controllerpublic class TestController {    @Resource    private IRegisterService registerService;    @RequestMapping("test")    @ResponseBody    public void test1(String name) {        registerService.register(name);        log.info("执行同步调用结束");    }}

在浏览器中输入地址:http://localhost/test?name=nik

控制台输出:

handlerEvent: UserEntity(id=1, name=nik, msg=新用户注册同步调用)执行同步调用结束

三、使用示例:异步发布

1、在启动类添加异步注解@EnableAsync

2、在监听方法上添加注解@Async

@Async@EventListener(condition = "#entity.name != null and #entity.async ")public void handlerEventAsync(UserEntity entity) {    try {        TimeUnit.SECONDS.sleep(5);    } catch (InterruptedException e) {        e.printStackTrace();    }    log.info("handlerEventAsync: {}", entity);}

3、在service中添加异步发送方法

@Overridepublic void registerAsyn(String name) {    UserEntity entity = new UserEntity();    entity.setName(name);    entity.setId(1L);    entity.setMsg("新用户注册异步调用");    entity.setAsync(true);    applicationEventPublisher.publishEvent(entity);}

3、测试

@RequestMapping("test")@ResponseBodypublic void test(String name) {    registerService.registerAsyn(name);    log.info("执行异步调用结束");}

控制台输出:

执行异步调用结束handlerEventAsync: UserEntity(id=1, name=nik, msg=新用户注册异步调用)

四、使用示例:在事务提交后发布事件

比如,用户注册成功后给用户发送成功短信,那么注册成功必然是注册方法事务提交成功后才代表成功。

Spring提供了注解@TransactionalEventListener监听事务事件,在@EventListener基础上增加了属性phase,包含以下四个值:

AFTER_COMMIT,事务提交成功后,默认BEFORE_COMMIT,事务提交前AFTER_ROLLBACK,事务回滚后AFTER_COMPLETION,事务完成,AFTER_COMMIT或AFTER_ROLLBACK

1、自定义事务处理事件

public class RegisterCommitEvent extends ApplicationEvent {    @Getter    @Setter    private String msg;    @Getter    @Setter    private String name;    public RegisterCommitEvent(UserEntity source) {        super(source);        this.msg = source.getMsg();        this.name = source.getName();    }}

2、在处理方法上添加事务注解,@Transactional

@Override@Transactionalpublic void registerCommit(String name) {    UserEntity entity = new UserEntity();    entity.setName(name);    entity.setMsg("新用户注册事务提交事件");    RegisterCommitEvent registerEvent = new RegisterCommitEvent(entity);    userDao.save(entity);    // 发送事件    applicationEventPublisher.publishEvent(registerEvent);}

3、添加事务事件监听

@Async@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)public void handlerEventCmmit(RegisterCommitEvent event) {    try {        TimeUnit.SECONDS.sleep(5);    } catch (InterruptedException e) {        e.printStackTrace();    }    log.info("handlerEventCmmit: {}", event);}

4、测试

@RequestMapping("test")@ResponseBodypublic void test(String name) {    registerService.registerCommit(name);    log.info("执行事务调用结束");}

控制台输出:

执行事务调用结束handlerEventCmmit: RegisterCommitEvent[source=UserEntity(id=0, name=nik, msg=新用户注册事务提交事件)]

总结

Spring ApplicationEvent事件处理机制使用起来简单方便,可以对程序进行有效解耦。

虽然可以发送任意类型的对象,但是在实际业务中容易产生混乱,建议根据实际业务,定义好各类事件,并在监听方法中实现异步处理。

关键词:

相关文章

热文推荐

当前热讯:Spring ApplicationEvent事件实现本地事件驱动
当前热讯:Spring ApplicationEvent事件实现本地事件驱动

TransactionalEventListener,事务事件监听,可监听事......更多>

生态环境部:支持生态环保产业发展 积极培育绿色发展新动能
生态环境部:支持生态环保产业发展 积极培育绿色发展新动能

证券时报e公司讯,5月6日,生态环境部党组书记孙金龙......更多>

【老外在中国 我眼中的新时代】巴铁青年阿德:奋斗创造美好生活
【老外在中国 我眼中的新时代】巴铁青年阿德:奋斗创造美好生活

来自巴基斯坦的“90后”青年阿德,在中国生活近十年,......更多>

短暂性脑缺血发作与脑梗死鉴别_脑缺血梗死灶是大病吗-环球快看点
短暂性脑缺血发作与脑梗死鉴别_脑缺血梗死灶是大病吗-环球快看点

1、缺血性脑梗死一般称为腔隙性脑梗死。如果没有血管......更多>

排行推荐

魂王传说_关于魂王传说简述
魂王传说_关于魂王传说简述
小伙伴们,你们好,今天小夏来聊聊一篇关于魂王传说,... 更多>
添可品牌创始人钱东奇:洗地机渗透率不足10% 技术仍是核心竞争力
添可品牌创始人钱东奇:洗地机渗透率不足10% 技术仍是核心竞争力
科沃斯集团董事长、添可品牌创始人钱东奇日前在某在论... 更多>
巴菲特持股公司一季报曝光:绝大部分标的业绩超预期,可口可乐提价带动业绩上涨12%|环球今日报
巴菲特持股公司一季报曝光:绝大部分标的业绩超预期,可口可乐提价带动业绩上涨12%|环球今日报
随着美股进入财报季,巴菲特的“优等生”们也陆续发布... 更多>
2023年5月6日:时间是这些好公司的朋友,却是那些烂公司的敌人---周投资总结_最新快讯
2023年5月6日:时间是这些好公司的朋友,却是那些烂公司的敌人---周投资总结_最新快讯
本周沪深300指收盘于4016 88,本年沪深300指数上涨3... 更多>
苏丹快速支援部队领导人对冲突双方谈判表示欢迎 今日精选
当地时间5月6日,苏丹快速支援部队领导人达加洛发表声... 更多>
F1迈阿密站周五练习赛分析 法拉利与红牛的真实差距是多少?
通过对比法拉利与红牛在FP2中的排位赛模拟,维斯塔潘... 更多>
顶固集创:接受线上参与公司2022年度业绩网上说明会的投资者调研 当前聚焦
顶固集创(SZ300749,收盘价:8 13元)发布公告称,2... 更多>
2023年房贷利率降了多少?多城房贷利率下至3时代!
1、商业贷款:首套房贷款利率普遍调至4%以下,最低可... 更多>
天天速递!目标不明,内部混乱,如此大巴黎拿不下欧冠,能怪谁?
这套方案引入的球员更多,且可以对中轴线进行从中锋,... 更多>
别拿陈旧的恶意软件不当威胁 世界快播报
尽管MyDoom已经走过了近二十年的路,但是MyDoom的最新... 更多>
天天观焦点:上海票交所:前4月发生3次以上承兑人逾期的承兑人数量为1629家
上海票据交易所公告,2023年1月1日至4月30日,发生3次... 更多>
中国石化牵头成立氢能产业链建设专家咨询委员会 当前关注
据中国石化(600028)官博消息,在5月5日举行的氢能应用... 更多>
科大讯飞全球首款认知大模型AI学习机T20系列发布
据了解,科大讯飞(002230)AI学习机T20系列率先在语数... 更多>
天天速递!浙江宁波:在风险可控前提下,放宽房贷年龄限制激活老年人购房需求
浙江省宁波市地方金融监督管理局等部门近日发布《关于... 更多>

云图控股:原材料价格波动对复合肥

天天关注:巴菲特的卖出理由(兼费

再看2380_当前短讯

全球球精选!如何在北交所大涨之中

和平精英电脑版下载_学堂威龙下载|

520送男朋友什么礼物合适_520男生能

播报:张雪唐墨小说_林三张雪小说

贵州毕节七星关区:“校农结合”实

2023福建省纤维检验中心招聘高层次

工业和信息化部批复5G地空通信试验