使用Spring @Autowired List的责任链

在Spring 3.1中,有一种方法可以自动填充类型化的List,这在您想在代码中稍微进行去耦和清理时非常方便。

为了向您展示它是如何工作的,我将实现一个简单的责任链,该责任链将为通过的用户打印一些问候。

让我们从我们拥有的(唯一的)域类(用户)开始:

package com.marco.springchain;
public class User {private final String name;private final char gender;public User(String name, char gender) {super();this.name = name;this.gender = gender;}public String getName() {return name;}public char getGender() {return gender;}
}

然后,我们创建一个接口,该接口定义要在链中使用的命令对象的类型:

package com.marco.springchain;
public interface Printer {void print(User user);
}

这是Printer实现的通用类(模板)。

org.springframework.core.Ordered用于告诉AnnotationAwareOrderComparator我们希望如何对List进行排序。

如果不需要您的链来具有执行顺序,则无需实现Ordered接口并重写getOrder方法。

还要注意,这个抽象类返回Ordered.LOWEST_PRECEDENCE ,这是因为我希望一些打印机命令仅在链的末尾运行,并且我不在乎它们的执行顺序(我保证,以后一切都会更清楚!)。

GenericPrinter

这是我们的第一个真正的打印机命令。 我希望它在链中具有绝对优先级,因此顺序为HIGHEST_PRECEDENCE

package com.marco.springchain;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
@Component
public class HelloPrinter extends GenericPrinter {private static final String GREETING = 'Hello';@Overrideprotected String getGreeting() {return GREETING;}@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}
}

WelcomePrinter将作为第一个命令执行( 在高优先级命令之后 )。

package com.marco.springchain;
import org.springframework.stereotype.Component;
@Component
public class WelcomePrinter extends GenericPrinter {private static final String GREETING = 'Welcome to the autowired chain';@Overrideprotected String getGreeting() {return GREETING;}@Overridepublic int getOrder() {return 1;}
}

GoodbyePrinter将作为第二个命令执行

package com.marco.springchain;
import org.springframework.stereotype.Component;
@Component
public class GoodbyePrinter extends GenericPrinter {private static final String GREETING = 'Goodbye';@Overrideprotected String getGreeting() {return GREETING;}@Overridepublic int getOrder() {return 2;}
}

这两个命令需要在其他命令之后执行,但是我不在乎它们的特定顺序,因此我不会覆盖getOrder方法,而让GenericPrinter Ordered.LOWEST_PRECEDENCE为这两个命令返回Ordered.LOWEST_PRECEDENCE

package com.marco.springchain;
import org.springframework.stereotype.Component;
@Component
public class CleaningMemoryPrinter extends GenericPrinter {private static final String GREETING = 'Cleaning memory after';@Overrideprotected String getGreeting() {return GREETING;}
}
package com.marco.springchain;
import org.springframework.stereotype.Component;
@Component
public class CleaningSpacePrinter extends GenericPrinter {private static final String GREETING = 'Cleaning space after';@Overrideprotected String getGreeting() {return GREETING;}
}

这是链上下文。

Spring将扫描(请参阅spring-config.xml)配置文件中指定的包,它将看到类型化的( List<Printer> )列表,并且它将使用实现该类型的任何@Component的实例填充该列表。打印机。

为了对List进行排序,我们使用AnnotationAwareOrderComparator.INSTANCE ,它使用getOrder方法对List进行重新排序( 值最低的对象具有最高优先级(有点类似于Servlet“启动时加载”值 ) )。

package com.marco.springchain;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.stereotype.Component;
@Component
public class PrinterChain {@Autowiredprivate List<Printer> printers;@PostConstructpublic void init() {Collections.sort(printers, AnnotationAwareOrderComparator.INSTANCE);}public void introduceUser(User user) {for (Printer printer : printers) {printer.print(user);}}
}

src / main / resources中的spring-config.xml。

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xmlns:aop='http://www.springframework.org/schema/aop'xmlns:tx='http://www.springframework.org/schema/tx'xmlns:context='http://www.springframework.org/schema/context'xmlns:util='http://www.springframework.org/schema/util'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd' default-lazy-init='true'><context:component-scan base-package='com.marco.springchain'/>
</beans>

最后,一个主类来测试我们的链。

package com.marco.springchain;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext('spring-config.xml');PrinterChain printerChain = (PrinterChain) context.getBean('printerChain');printerChain.introduceUser(new User('Marco Castigliego', 'M'));printerChain.introduceUser(new User('Julie Marot', 'F'));}
}

输出:

Hello Mr Marco Castigliego
Welcome to the autowired chain Mr Marco Castigliego
Goodbye Mr Marco Castigliego
Cleaning space after Mr Marco Castigliego
Cleaning memory after Mr Marco Castigliego
Hello Mrs Julie Marot
Welcome to the autowired chain Mrs Julie Marot
Goodbye Mrs Julie Marot
Cleaning space after Mrs Julie Marot
Cleaning memory after Mrs Julie Marot

希望您喜欢这个例子。

参考: 使用来自我们的JCG合作伙伴 Marco Castigliego的Spring @Autowired List的责任链,位于“ 删除重复和修复不良名称”博客中。

翻译自: https://www.javacodegeeks.com/2012/11/chain-of-responsibility-using-spring-autowired-list.html

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

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

相关文章

设计模式 建造者模式 与 Spring Bean建造者 BeanDefinitionBuilder 源码与应用

建造者模式 定义: 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示主要作用: 在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象如何使用: 用户只需要给出指定复杂对象的类型和内容, 建造者模式负责按顺序创建复杂对象…

java 布隆过滤器_什么是布隆过滤器(Bloom Filter)?

在日常工作中&#xff0c;有一个比较常见的需求&#xff0c;就是需要判断一个元素是否在集合中。例如以下场景&#xff1a;给定一个IP黑名单库&#xff0c;检查指定IP是否在黑名单中&#xff1f;在接收邮件的时候&#xff0c;判断一个邮箱地址是否为垃圾邮件&#xff1f;在文字…

STM32上使用JSON

一、STM32工程中添加JSON 最近在一网2串项目&#xff0c;串口和网口之间可能需要定义一下简单的通信协议&#xff0c;而通信协议上则需要去定义一下通信的数据格式&#xff0c;上次听剑锋说要用Json来定义&#xff0c;目前查了下资料具体如何去应用还不 会。因为最新的KEIL上支…

Flex 学习

Flex案例一&#xff1a; 1 <html>2 <head>3 <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> 4 <title>无标题</title>5 <style type"text/css">6 body,h1,h2,h3,h4,…

Cocos2d-X中实现自己定义菜单处理事件

当用户点击再松开后才会响应菜单事件&#xff0c;而在游戏中有些游戏须要玩家点击后就处理事件。如玩坦克大战的时候&#xff0c;玩家是点击一下就发射子弹。并是点击松手后发射子弹&#xff0c;在Cocos2d-X中没有这样的消息。以下就通过自己定义的方式实现当用户点击后就调用处…

java linkedhashset_java之LinkedHashSet

LinkedHashSet是Set集合的一个实现&#xff0c;具有set集合不重复的特点&#xff0c;同时具有可预测的迭代顺序&#xff0c;也就是我们插入的顺序。并且linkedHashSet是一个非线程安全的集合。如果有多个线程同时访问当前linkedhashset集合容器&#xff0c;并且有一个线程对当前…

使用Spring Integration轮询http端点

如果您想用Spring Integration编写一个流程来轮询HTTP端点并从http端点收集一些内容以进行进一步处理&#xff0c;那有点不直观。 Spring Integration提供了几种与HTTP端点集成的方式- Http出站适配器–将消息发送到http端点 Http出站网关–将消息发送到http端点并收集响应作…

python模块离线安装_离线安装db2的python模块ibm_db

1、为什么要离线安装 没网&#xff0c;在银行工作&#xff0c;服务器环境配置&#xff0c;完全离线&#xff08;本来五分钟搞定的事情&#xff0c;非要搞一天。我服&#xff01;&#xff01;&#xff09; 2、安装步骤 视情况而定。 3。一个下载db2的client包&#xff0c;官网下…

Jmeter 场景设计

今天的业务场景是&#xff1a; 1.管理员登录后台---登录成功后添加一个某类型的产品---产品添加成功后&#xff0c;再为该产品添加10个排期。 2.管理员登录后台--登录成功后添加多个不同类型产品---产品全部添加完成后&#xff0c;依次为所有产品添加10个排期。 这是两种不同的…

Android IPC机制(五)用Socket实现跨进程聊天程序

1.Socket简介 Socket也称作“套接字“&#xff0c;是在应用层和传输层之间的一个抽象层&#xff0c;它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。它分为流式套接字和数据包套接字&#xff0c;分别对应网络传输控制层的TCP和UDP协议。TCP协…

ArcGIS 网络分析[4] 网络数据集深入浅出之连通性、网络数据集的属性及转弯要素...

前面介绍完了如何创建网络数据集、如何使用网络分析功能&#xff0c;当然还有的读者会迷惑于一些更深层次的问题&#xff0c;比如网络数据集的连通性问题等。 因为不可能面面俱到&#xff0c;我只能挑重点来阐述&#xff0c;我觉得网络数据集的连通性、属性和转弯是初学者中比较…

java获取byte 长度_java获取字节的长度.

我们经常要获取中文,数字,或者英文字符所占字节的长度,下面就列出各种编码格式下所占字节的长度:代码如下:package pack.java.midea.dao;import java.io.UnsupportedEncodingException;/*** 测试;* author zhouhaitao* 2012-5-17*/public class Test {/*** param args* throws …

Batoo JPA –比领先的JPA提供商快15倍

介绍 我早在2000年代就喜欢JPA 1.0。 我甚至在稳定版本发布之前就将其与EJB 3.0一起使用。 我非常喜欢它&#xff0c;因此我为JBoss 3.x实现贡献了一些零碎的部分。 那时我们公司规模还很小。 创建新功能和应用程序比性能更重要&#xff0c;因为我们有很多想法&#xff0c;我…

python软件是哪个国家的品牌_有哪些好用的软件被国人误认为是外国研发的?

国产软件被标榜上了英文&#xff0c;即便不是英文&#xff0c;用拼音写出来&#xff0c;也会有人误认为是国外的软件。因为这样可以显得高大上&#xff0c;为什么我们会有这样的想法&#xff0c;是崇洋媚外吗&#xff0c;并不是&#xff0c;而是之前的国产软件的确有不少让我们…

简单的Session案例 —— 一次性验证码

一次性验证码的主要目的就是为了限制人们利用工具软件来暴力猜测密码&#xff0c;其原理与利用Session防止表单重复提交的原理基本一样&#xff0c;只是将表单标识号变成了验证码的形式&#xff0c;并且要求用户将提示的验证码手工填写进一个表单字段中&#xff0c;而不是通过表…

[BZOJ2064]分裂

[BZOJ2064]分裂 试题描述 背景&#xff1a; 和久必分&#xff0c;分久必和。。。 题目描述&#xff1a; 中国历史上上分分和和次数非常多。。通读中国历史的WJMZBMR表示毫无压力。 同时经常搞OI的他把这个变成了一个数学模型。 假设中国的国土总和是不变的。 每个国家都可以用他…

CSS3选择器

基本选择器 回顾选择器 通配符选择器元素选择器类选择器ID选择器后代选择器新增基本选择器 子元素选择器相邻兄弟选择器通用兄弟选择器群组选择器 子元素选择器 概念&#xff1a;子元素选择器只能选择某元素的子元素 语法&#xff1a;父元素 > 子元素 &#xff08;Fathe…

eclipse java工程目录_转载:Eclipse下的java工程目录

对新手来讲&#xff0c;一个Java工程内部的多个文件夹经常会让大家困惑。更可恶的是莫名其妙的路径问题&#xff0c;在Eclipse编写Java程序中&#xff0c;出现频率最高的错误很可能就是路径问题。这些问题原因其实都是一个&#xff0c;就是关于Java工程内的文件结构理解不清&am…

作为JBoss AS 7模块运行Drools 5.4.0 Final

Drools 5引入了业务逻辑集成平台&#xff0c;该平台为规则&#xff0c;工作流和事件处理提供了统一的集成平台。 它是从头开始设计的&#xff0c;因此每个方面都是一流的公民&#xff0c;毫不妥协。 Drools 5已分为4个主要子项目&#xff1a; Drools Guvnor&#xff08;BRMS …

postgres 支持的线程数_线程池被打满了怎么处理呢,你是否真的了解线程池?

0、前言线程池&#xff0c;顾名思义就是线程的池子&#xff0c;在每次需要取线程去执行任务的时候&#xff0c;没必要每次都创建新线程执行&#xff0c;线程池就是起着维护线程的作用&#xff0c;当有任务的时候就取出一个线程执行&#xff0c;如果任务执行完成则把线程放回到池…