spring3.0异步_在Spring 4.2中更简单地处理异步事务绑定事件

spring3.0异步

介绍

如您可能已经知道的(例如,从我以前的博客文章中 ),不再需要创建一个单独的类来实现带有onApplicationEvent方法的ApplicationListener ,以便能够对应用程序事件做出响应(包括来自Spring Framework本身和我们自己的域事件)。 从Spring 4.2开始,添加了对注释驱动的事件侦听器的支持。 在方法级别使用@EventListener就足够了,它会在@EventListener自动注册相应的ApplicationListener

@EventListenerpublic void blogAdded(BlogAddedEvent blogAddedEvent) {externalNotificationSender.blogAdded(blogAddedEvent);}

请注意 ,在事件中使用域对象有明显的缺点,在许多情况下也不是最好的主意。 代码示例中的伪域对象用于不引入不必要的复杂性。

交易绑定事件

简单紧凑。 对于“标准”事件,一切看起来都很不错,但在某些情况下,需要在事务提交(或回滚)之后执行一些操作(通常是异步操作)。 那是什么 是否可以使用新机制?

业务需求

首先,是一个小题外话-业务需求。 让我们想象一下超级精美的博客聚合服务。 每次添加新博客时都会生成一个事件。 订阅的用户可以接收SMS或推送通知。 可以在将博客对象计划保存在数据库中之后发布该事件。 但是,在提交/刷新失败(违反数据库约束,ID生成器出现问题等)的情况下,整个数据库事务都会回滚。 许多愤怒的用户,带有不完整的通知,将出现在门口……

技术问题

在现代的事务管理方法中,事务是声明式配置的(例如,使用@Transactional批注),并且在事务作用域的结尾(例如,方法的结尾)触发提交。 总的来说,这非常方便,而且出错的可能性要小得多(与编程方法相比)。 另一方面,提交(或回滚)是在代码外自动完成的,因此我们无法以“经典方式”做出React(即在调用transaction.commit()之后的下一行中的publish事件)。

老学校实施

不可或缺的Tomek Nurkiewicz提出了Spring的一种可能的解决方案(也是一种非常优雅的解决方案)。 它使用TransactionSynchronizationManager来注册当前线程的事务同步。 例如:

@EventListenerpublic void blogAddedTransactionalOldSchool(BlogAddedEvent blogAddedEvent) {//Note: *Old school* transaction handling before Spring 4.2 - broken in not transactional contextTransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {@Overridepublic void afterCommit() {internalSendBlogAddedNotification(blogAddedEvent);}});}

所传递的代码在Spring事务工作流中的适当位置执行(对于这种情况,“恰好”在提交之后)。

为了提供对非事务上下文中执行的支持(例如,在不关心事务的集成测试用例中),可以将其扩展为以下形式,以确保不会因java.lang.IllegalStateException: Transaction synchronization is not active而失败java.lang.IllegalStateException: Transaction synchronization is not active异常:

@EventListenerpublic void blogAddedTransactionalOldSchool(final BlogAddedEvent blogAddedEvent) {//Note: *Old school* transaction handling before Spring 4.2//"if" to not fail with "java.lang.IllegalStateException: Transaction synchronization is not active"if (TransactionSynchronizationManager.isActualTransactionActive()) {TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {@Overridepublic void afterCommit() {internalSendBlogAddedNotification(blogAddedEvent);}});} else {log.warn("No active transaction found. Sending notification immediately.");externalNotificationSender.newBlogTransactionalOldSchool(blogAddedEvent);}}

在缺少活动事务的情况下,通过进行此更改,可以立即执行提供的代码。 到目前为止,一切正常,但让我们尝试在Spring 4.2中使用注释驱动的事件侦听器实现相同的目的。

Spring 4.2+实施

除了@EventListener之外,Spring 4.2还提供了另一个注解@TransactionalEventListener

@TransactionalEventListenerpublic void blogAddedTransactional(BlogAddedEvent blogAddedEvent) {externalNotificationSender.newBlogTransactional(blogAddedEvent);}

执行可以绑定到标准事务阶段:提交之前/之后,回滚之后或完成之后(提交或回滚)。 默认情况下,只有在事件的边界内发布事件时,它才会处理事件。 在其他情况下,该事件将被丢弃。

为了支持在非事务上下文中的执行,可以使用falbackExecution标志。 如果设置为“ true”,则如果没有事务在运行,则将立即处理事件。

@TransactionalEventListener(fallbackExecution = true)public void blogAddedTransactional(BlogAddedEvent blogAddedEvent) {externalNotificationSender.newBlogTransactional(blogAddedEvent);}

摘要

在Spring 4.2中引入的注释驱动的事件侦听器延续了减少基于Spring(Boot)的应用程序中样板代码的趋势。 无需手动创建ApplicationListener实现,无需直接使用TransactionSynchronizationManager只需一个具有正确配置的注释即可。 硬币的另一面是,要找到所有事件侦听器会有些困难,尤其是在我们的整体应用程序中有数十个事件侦听器的情况下(尽管可以很容易地对其进行分组)。 当然,新方法只是在给定用例中有用或没有用的一种选择。 尽管如此,Spring(Boot)的另一个魔力泛滥到了我们的系统中。 但是也许抵抗是徒劳的?

抵抗是徒劳的吗?资料来源:http://en.memory-alpha.wikia.com/wiki/Borg_cube

抵抗是徒劳的吗?
资料来源: http : //en.memory-alpha.wikia.com/wiki/Borg_cube

请注意,Spring Framework 4.2是Spring Boot 1.3的默认依赖项(在编写1.3.0.M5时可用)。 另外,可以在Gradle / Maven中为Spring Boot 1.2.5手动升级Spring Framework版本–在大多数情况下应该可以使用。

  • 可以从GitHub获得代码示例。

顺便说一句,为该博客文章编写示例使我有了使用Spring 4.1中引入的新测试事务管理系统的第一种真正能力(过去,我仅在Spring培训课程中提到过它)。 可能,我会尽快写更多有关它的内容。

翻译自: https://www.javacodegeeks.com/2015/10/simpler-handling-of-asynchronous-transaction-bound-events-in-spring-4-2.html

spring3.0异步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java实现ldap服务器_Java到LDAP教程(包括如何安装LDAP服务器/客户端)

java实现ldap服务器本教程将向您展示如何编写Java代码以与LDAP交互。 但是在执行此操作之前,我们需要在计算机上设置LDAP服务器和客户端。 如果此时您不确定到底是什么LDAP,建议您使用这篇文章,其中提供了一个很好的定义示例。 (…

java 程序增加 防盗_防盗Java EE –保护Java EE企业应用程序的安全

java 程序增加 防盗redev离我们仅有几天的路程,我受邀作了两次演讲。 其中之一是关于我最喜欢的主题:安全性和Java EE。 它旨在实现两个目标。 一方面向典型的Java EE开发人员介绍整个应用程序安全过程和主要目标。 而且还要查看有关Java EE在满足典型需…

js内存泄露 垃圾回收_Java内存体系结构(模型),垃圾回收和内存泄漏

js内存泄露 垃圾回收Java内存架构(Java内存模型) 上面是堆的Java内存模型以及Java虚拟机(JVM)中运行的任何Java应用程序的PermGen。 还提供了比率,以使您更好地了解如何在每种生成类型之间分配允许的内存。 以上所有内…

qlineedit文本改变时_PyQt5 QLineEdit(单行编辑器) 学习

QLineEdit is a widget that allows to enter and edit a single line of plain text. There are undo and redo, cut and paste, and drag & drop functions available for the widget.代码:# codingutf-8from PyQt5.QtWidgets import QApplication, QWidget,\…

jboss7.0.2_红帽JBoss企业应用平台7.0 ALPHA发布了!

jboss7.0.2红帽JBoss企业应用程序平台7(JBoss EAP 7)是基于开放标准构建并符合Java Enterprise Edition 7规范的中间件平台。 它将WildFly Application Server 10与高可用性群集,消息传递,分布式缓存和其他技术集成在一起。 现在可…

sts集成jboss_与JBoss BPM Travel Agency更新了Modern BPM数据集成

sts集成jboss不久前,我们启动了一个规模较大的JBoss Travel Agency演示项目,以展示JBoss BPM Suite的一些更有趣的功能。 我们提供了一系列视频 ,不仅向您展示了如何安装它,项目中各种规则和流程工件的含义,还向您介绍…

java 线程组作用_Java线程组(ThreadGroup)使用

JDK 对线程组类注释:A thread group represents a set of threads. In addition, a thread group can also include other thread groups. The thread groups form a tree in which every thread group except the initial thread group has a parent.A thread is a…

java左上角图标太小_Eclipse在高分屏下图标过小的解决方法

自己败了一台Surface Pro 4,打算用来看PDF、练代码。安装了Eclipse并且打开之后,发现图标显示极其细小,肉眼几乎无法看清了。这是由于Eclipse对高分屏没有作适配导致的。Windows 10本身对于高分屏的支持已是相当不错,苏菲4的屏幕分…

activiti 多租户_Activiti中具有独立数据库架构的多租户

activiti 多租户我们过去听到的一项功能请求是以多租户方式运行Activiti引擎,使租户的数据与其他数据隔离。 当然,在某些云/ SaaS环境中,这是必须的。 几个月前,波恩大学的学生拉斐尔吉伦(Raphael Gielen)…

jigsaw kaggle_使用Project Jigsaw的JDK 9 Early Access上的Eclipse IDE

jigsaw kaggle几周前,我写了关于在Java 9上运行Eclipse Neon的文章 (尽管,我在帖子标题中错误地且令人尴尬地留下了“火星”)。 值得注意的是,我列出的步骤也适用于带有Project Jigsaw (Java模块化&#xf…

win7 activemq_带有骆驼,ActiveMQ,Elasticsearch的关键HL7用例

win7 activemqML7上的HL7是可以说HL7协议格式的系统的一种非常常见的传输机制。 JBoss Fuse是一个非常强大的微服务样式集成平台,在为关键医疗保健提供者构建灵活,有弹性,高可用性的集成方案方面拥有良好的经验。 此外,在JCAPS上替…

java boundary_上传文件multipart form-data boundary 说明

含义 ENCTYPE"multipart/form-data" 说明:通过 http 协议上传文件 rfc1867协议概述,客户端发送内容构造。概述在最初的 http 协议中,没有上传文件方面的功能。 rfc1867为 http 协议添加了这个功能。客户端的浏览器,如 M…

crud-table_我个人的CRUD故事-或我如何来到CUBA平台

crud-table在此博客文章中,我想介绍一下我如何使用CUBA平台以及该工具的好处。 在我年轻的“业务应用程序开发”历史上,我将深入探讨各个阶段,只是给您一些背景知识。 因此,让我们从如何进入典型的CRUD应用程序开始,以…

python api接口生成_Django 自动生成api接口文档教程

最近在写测试平台,需要实现一个节点服务器的api,正好在用django,准备使用djangorestframework插件实现。需求实现一个接口,在调用时,通过传递的参数,直接运行对应项目的自动化测试环境Python3.6 ,PyCharm,W7项目结构功…

eclipse clean_Clean Sheet – Windows 10的人体工程学Eclipse主题

eclipse cleanClean Sheet是适用于Windows 10的符合人体工程学的Eclipse主题。它基于干净,低眩光的外观和感觉,旨在减轻视觉疲劳和眼睛疲劳。 它融合了均衡的颜色选择,可以突出谐波语法并注重可读性。 除自定义滚动条外,它还努力满…

什么时候需要使用cqrs_在CQRS读取模型中使用Hibernate进行快速开发

什么时候需要使用cqrs在本文中,我将分享一些在CQRS读取模型中使用Hibernate工具进行快速开发的技巧。 为什么要Hibernate? Hibernate非常流行。 从外观上看,它也很容易,而从内部看,它却相当复杂。 它可以很容易地上手…

java 隐藏了什么_JAVA程序中封装与隐藏是什么意思

qq_遁去的一_1隐藏就是封装吧。。。。封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一…

esb 和 开源esb_如果今天完成,ESB会是什么样子?

esb 和 开源esbJavaOne 2015即将结束,这又是一次很棒的社区活动。 我和Rafael进行了两次会议和一次HOL 。 我最喜欢的会议之一实际上是:谈论ESB,如果今天完成的话。 我以为那是过去? 我通常也倾向于这样说。 但是,系统…

五皇后问题 java_Java的5个古怪问题

五皇后问题 java我们有机会接触到一些最奇怪的Java难题 即使是最有经验的Java开发人员,也会在这篇文章中发现令人困惑的问题。 或者至少是有趣的(绝对不公平)。 在经历了Java Deathmatch冒险之后,我们决定这次发布一系列不同的问…

java加密成固定长度_Java使用MD5加密,生成的密文长度只有31位

在使用MD5加密时,生成的密文长度只有31位,该怎么解决?代码如下:public static String toMd5(String str) {String re null;byte encrypt[];try {byte[] tem str.getBytes();MessageDigest md5 MessageDigest.getInstance("…