spring 4.3.x_如何在Spring 3.x中使用事件

spring 4.3.x

创建松耦合应用程序的概念和技术很多,Event是其中之一。 事件可以消除代码中的许多依赖关系。 有时没有事件,很难实施SRP *。 Java中的Observable接口可以帮助我们实现事件(通过Observer Pattern)。

但是,等等,这篇文章的目标是关于Spring Event的快速教程。 Spring具有一些用于创建事件驱动应用程序的好工具。 您可以在一个bean中引发一个特定的事件,并在另一个bean中监听它。

想象一个简单的应用程序具有以下要求:

  • 有些订单的状态可能不同
  • 当订单处于“已交付”或“已推迟”状态时,我们需要向客户发送电子邮件

满足需求的第一个(但不是最好的)解决方案是在我们的订单模型中发送电子邮件,但是存在一些缺陷:

  • 订单不负责发送电子邮件。
  • 如果您遵循域驱动原则,那么Order是一个域对象,但Email Sender可能是一项服务(不同于Domain Service),因此您不能在模型中使用它。

另一个解决方案是在更改其状态后在Order模型中引发一些事件。 我不关心订购在引发此事件之后会发生什么。 在我们的示例中,我们需要收听特定类型的事件,对其进行分析并开展一些业务(发送电子邮件)。

@Configurablepublic class Order implements ApplicationEventPublisherAware {private final String orderId;private final Date createDate;private final CustomerInfo customerInfo;private ApplicationEventPublisher eventPublisher;private Date lastUpdateDate;private Status status;public Order(String orderId, CustomerInfo customerInfo) {this.orderId = orderId;this.customerInfo = customerInfo;status = Status.MODIFIABLE;this.createDate = new Date();this.lastUpdateDate = this.createDate;}public String getOrderId() {return orderId;}public void checkOut() {if (status == Status.DELIVERED) {throw new IllegalStateException(String.format("Order is already delivered"));}this.status = Status.CHECKED_OUT;this.lastUpdateDate = new Date();}public void deliver() {if (this.status != Status.CHECKED_OUT && this.status != Status.POSTPONED) {throw new IllegalStateException(String.format("Order status should be CHECKED OUT for delivery to be called. but is : %s", status));}this.status = Status.DELIVERED;this.lastUpdateDate = new Date();this.eventPublisher.publishEvent(new OnOrderDelivered(this));}public void postponeDelivery() {if (status != Status.CHECKED_OUT && status != Status.POSTPONED) {throw new IllegalStateException(String.format("Can not postpone delivery in this state: %s", status));}this.status = Status.POSTPONED;this.lastUpdateDate = new Date();this.eventPublisher.publishEvent(new OnOrderPostponed(this));}public Status getStatus() {return status;}public CustomerInfo getCustomerInfo() {return customerInfo;}public Date getLastUpdateDate() {return lastUpdateDate;}public Date getCreateDate() {return createDate;}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.eventPublisher = applicationEventPublisher;}public static enum Status {MODIFIABLE,CHECKED_OUT,POSTPONED,DELIVERED,CANCELED;}}

如您所见,Order是一个可配置的类,如果您以前从未使用过此概念,请不要为之苦恼。 对于这篇文章,您只需要知道可配置类可以在任何地方使用new关键字创建,但是它们是由spring管理的,因此您可以向其中注入其他bean或将大多数spring功能与它们一起使用。 我保证会尽快发布有关它的文章。

Order类实现org.springframework.context.ApplicationEventPublisherAware接口。 此接口具有名称为setApplicationEventPublisher的setter方法,该方法表示要在您的类中使用的ApplicationEventPublisher 。 如您在deliver方法中所见,我们使用该对象发布事件( this.eventPublisher.publishEvent(new OnOrderDelivered(this)) )。 您可以发布扩展org.springframework.context.ApplicationEvent每个事件。 当订单被推迟时,我们引发了另一个事件OnOrderPostponed

public abstract class OnOrderStatusChanged extends ApplicationEvent {private final Order order;public OnOrderStatusChanged(Order source) {super(source);this.order = source;System.out.println(String.format("Order:%s status is changed to %s", source.getOrderId(), source.getStatus()));}public Order getOrder() {return order;}}public class OnOrderDelivered extends OnOrderStatusChanged {public OnOrderDelivered(Order order) {super(order);}}public class OnOrderPostponed extends OnOrderStatusChanged {public OnOrderPostponed(Order order) {super(order);}}

OnOrderStatusChanged是一个抽象类,OnOrderDelivered和OnOrderPostponed对其进行了扩展。 到现在为止,我们可以创建活动并发起活动。 现在,如果您创建一个弹簧测试并调用订单的传递方法,您将看到“ Order:X状态更改为DELIVERED”。最后一步是在发布这些事件时执行某些操作。 这些方法提出后,我们希望向客户发送电子邮件。 另外,对于客户来说,在订单处于交付状态时发布产品也很有价值。 侦听器是实现通用ApplicationListener接口的简单Bean。 此接口中的参数类型是您要监听的事件的类型。 可以将参数类型定义为父级,并侦听其所有子级。 例如在我们的模型中,如果我们使用OnOrderStatusChanged侦听器将捕获OnOrderDeliveredOnOrderPostponed所有事件

在我们的方案中,它可能适合发送电子邮件。 但是我们不使用此模型,而是为它们创建两个不同的侦听器。

如您所见,它们的代码非常简单

@Servicepublic class OrderDeliveredEmailSender implements ApplicationListener,Ordered {@Overridepublic void onApplicationEvent(OnOrderDelivered event) {System.out.println(String.format("Message sent for delivered order to:%s ORDER-ID:%s",event.getOrder().getCustomerInfo().getEmail(),event.getOrder().getOrderId()));}@Overridepublic int getOrder() {return 100;}}@Servicepublic class OrderPostponedEmailSender implements ApplicationListener {@Overridepublic void onApplicationEvent(OnOrderPostponed event) {System.out.println(String.format("Message sent for postponed order to:%s ORDER-ID:%s", event.getOrder().getCustomerInfo().getEmail(), event.getOrder().getOrderId()));}}

当引发对应事件时,这两个bean将触发onApplicationEvent。 为了将产品发布给客户,我们需要为OnOrderDelivered事件创建另一个监听器。

@Servicepublic class OnOrderDeliveredPost implements ApplicationListener,Ordered {@Overridepublic void onApplicationEvent(OnOrderDelivered onOrderDelivered) {System.out.println(String.format("Order:%s is posting for customer.",onOrderDelivered.getOrder().getOrderId()));}@Overridepublic int getOrder() {return 1000;}}

如您所见,当状态为“已交付”时,此侦听器会将产品发送给客户。 但是等一下什么是Ordered接口? 如果您没有使用org.springframework.core.Ordered接口,那么知道使用此接口可以定义集合中bean之间的顺序是很有价值的。 在我们的方案中,客户喜欢在将产品发布给他之前收到一封电子邮件。 为此,这两个类实现了Ordered接口,不要忘记最低的顺序具有最高的优先级。

*单一责任原则

  • 您可以从以下网址下载源代码: https : //github.com/psycho-ir/spring-event.git

参考: Just另一个Java博客博客中的JCG合作伙伴 Soroosh Sarabadani的Spring 3.x中的如何使用Events 。

翻译自: https://www.javacodegeeks.com/2013/08/how-to-use-events-in-spring-3-x.html

spring 4.3.x

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

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

相关文章

java接口安全怎么处理_Restful API 接口安全性设计

1.API接口设计规范2.安全性设计a.白名单限制仅接受特定系统的请求响应,调用方的IP地址需要在本系统中报备,否则无法调用b.合法身份合法性验证Basic Authentication :这种方式是直接将用户名和密码放到Header中,使用 Authorization: Basic Zm9…

使用Spring开发Java RESTful Web服务的7个理由

REST现在已成为开发Web服务的标准方法,涉及Java时,可以使用许多框架和库,例如JAX-RS,Restlet,Jersey,RESTEasy,Apache CFX等,但是我鼓励Java开发人员使用Spring框架来开发Java。开发…

Java面向对象(7)--package和import关键字

package关键字 ①为了更好的实现项目中类的管理,提供包的概念 ②使用package声明类或接口所属的包,声明在源文件的首行 ③包,属于标识符,遵循标识符的命名规则、规范( xxxyyyzzz) ④每"."一次,就代表一层文…

java圆形排列_位图排序java版

1、《编程珠玑》第一章第一题就相当的精彩,做个笔记。题目如下:输入: 一个包含n个正整数的文件,每个正整数小于n,n等于10的7次方(一千万)。并且文件内的正整数没有重复和关联数据。输出: 输入整数的升序排列约束: 限制在1M左右…

(3.1)HarmonyOS鸿蒙单击事件4种写法

第二种和第四种常用 实现步骤: 1.通过id找到组件。 2.给需要的组件设置单击事件。 3.实现ClickedListener接口。 4.重写onClicked方法。 第一种,自定义实现类(在当前类外面写实现类) ①MainAbilitySlice.java文件 package com.example.yem…

JSON指针:JSON-P 1.1概述系列

Java EE 8包括对JSON处理API的更新,并使其与JSON的最新IEFT标准保持同步。 他们是: JSON指针 (RFC 6901) JSON修补程序(RFC 6902) JSON合并补丁(RFC 7396) 我将在这个迷你系列中…

Java获取oracle字段注释_java读取ORACLE数据库表字段信息以及注释信息

最近在做编程工具,便于快速开发程序,用过太多框架,但是发觉只有自己制作代码工具才开发起来痛快。这个类是用来读取oracle数据库表结构的,也包括列的注释,对于生成代码有很好的帮助。1.[文件] OracleTable.java ~ 3KB …

(3.2)HarmonyOS鸿蒙双击事件

跟单击事件类似,双击事件也有4种写法,这里采用当前类作为实现类这种写法,其他写法可以参见《单击事件的4种写法》。不同的是双击事件需要的是Component.DoubleClickedListener。 实现步骤: 1.通过id找到组件。 2.给需要的组件设置双击事件。…

java文件和xml文件_用Java分割大型XML文件

java文件和xml文件上周,我被要求用Java编写一些东西,该东西能够将一个30GB的XML文件拆分为可配置文件大小的较小部分。 文件的使用者将是一个中间件应用程序,该应用程序在XML的大尺寸方面存在问题。 在幕后,它使用某种DOM解析技术…

oracle java 并发_【转】JAVA并发教程(ORACLE官网资料)

本文是Oracle官方的Java并发相关的教程,感谢并发编程网的翻译和投递。计算机的使用者一直以为他们的计算机可以同时做很多事情。他们认为当其他的应用程序在下载文件,管理打印队列或者缓冲音频的时候他们可以继续在文字处理程序上工作。甚至对于单个应用…

(3.3)HarmonyOS鸿蒙长按事件

跟单击事件类似,长按事件也有4种写法,这里采用当前类作为实现类这种写法,其他写法可以参见《单击事件的4种写法》。 实现步骤: 1.通过id找到组件。 2.给需要的组件设置长按事件。 3.本类实现LongClickedListener接口。 4.重写onLongClicked方…

部署Spring Boot Angular App(Maven和Tomcat)的4种方法

在上一篇有关Spring Boot angular 5的文章中 ,我们使用Spring Boot angular 5实现了一个完整的堆栈端到端Web应用程序。在本文中,我们将讨论在tomcat上部署Spring Boot和Angle App的不同方法。 我们将创建一个具有后端(服务器)和前…

java中true转换为int_在Java中将字节转换为int的最优雅的方式

示例代码:int a 255;byte b (byte) a;int c b & 0xff; // Here be dragonsSystem.out.println(a);System.out.println(b);System.out.println(c);所以我们从一个整数值255开始,将它转换成一个字节(变为-1),然后使用魔术公式将其转换成…

(3.4)HarmonyOS鸿蒙滑动事件三个动作

接口名:TouchEventListener 滑动事件里面分为三个动作:按下,移动,抬起 PRIMARY_POINT_DOWN:按下 POINT_MOVE:移动 PRIMARY_POINT_UP:抬起 手机坐标: 手机左上角的点为原点。向右为…

计算机二级web题目(8.3)--简单应用题2

前些天发现了一个巨牛的人工智能学习电子书,通俗易懂,风趣幽默,无广告,忍不住分享一下给大家。(点击跳转人工智能学习资料) 1.在考生文件夹下的Web3目录中,存有3.htm文件,该文件不完…

计算机二级web题目(8.4)--综合应用题2

前些天发现了一个巨牛的人工智能学习电子书,通俗易懂,风趣幽默,无广告,忍不住分享一下给大家。(点击跳转人工智能学习资料) 1.在考生文件夹下的Web5目录中,存有5.htm文件,该文件不完…

创建存储,修改存储_安全地创建和存储密码

创建存储,修改存储几乎每次涉及用户配置文件时,都必须管理用户凭据,从而能够创建和存储用户密码。 通常应该使用哈希密码和盐分密码来准备数据库公开和通过使用Rainbow表进行哈希逆转。 但是,找到以明文形式存储的密码并不少见(很…

mysql把一行保存到另一个表_MYSQL:如何复制整个行从一个表到另一个在MySQL与第二个表有一个额外的列?...

为了完善Zed的答案,并回答你的评论:INSERT INTO dues_storage SELECT d.*, CURRENT_DATE() FROM dues d WHERE id 5;见TJ Crowder的评论最安全的方法是完全指定插入和提取的列。 (对于应用程序)没有任何保证,这些将是您认为可能的顺序。inse…

Spring Security中的SecurityContext和SecurityContextHolder是什么?

SecurityContext和SecurityContextHolder是Spring Security的两个基本类。 SecurityContext用于存储当前经过身份验证的用户的详细信息,也称为原理。 因此,如果必须获取用户名或任何其他用户详细信息,则需要首先获取此SecurityContext 。 Sec…

codemirror java代码_codemirror使用(示例代码)

JS使用使用bower下载javascript bower i codemirror引入样式文件html 引入js文件html 文档结构html 初始化javascript // mode: "text/javascript", // mode: "text/css" window.onload function(){ var myCodeMirror CodeMirror.fromTextArea(document.…