spring 注释的作用_Spring的@Primary注释在起作用

spring 注释的作用

Spring是一个永不停息的框架。 这是因为它提供了许多不同的解决方案,使我们(开发人员)无需编写数百万行代码即可完成我们的任务。 取而代之的是,我们能够以更具可读性,更标准化的方式进行操作。 在这篇文章中,我将尝试描述最有可能为大家所熟知的功能之一,但我认为其重要性被低估了。 我将要讨论的功能是@Primary批注。

问题

在我从事的几个项目中,我们遇到了一个常见的业务问题–我们有一个进入更复杂逻辑的入口–一些容器,该容器会将其他几个处理器的结果收集到一个输出中(例如map-filter-reduce函数编程中的函数)。 在某种程度上,它类似于Composite模式。 综上所述,我们的方法如下:

  1. 我们有一个容器,其中包含自动实现共同接口的处理器列表
  2. 我们的容器实现了与自动装配列表元素相同的接口
  3. 我们希望使用该容器的客户端类使整个处理工作透明化-他只对结果感兴趣
  4. 处理器具有一些逻辑(谓词),处理器可将其应用于当前输入数据集
  5. 然后将处理结果合并到一个列表中,然后缩减为单个输出

有很多方法可以解决此问题-我将介绍一种使用Spring和@Primary批注的方法。

解决方案

让我们从定义我们的用例如何适应上述前提开始。 我们的数据集是一个Person类,如下所示:

人.java

package com.blogspot.toomuchcoding.person.domain;public final class Person {private final String name;private final int age;private final boolean stupid;public Person(String name, int age, boolean stupid) {this.name = name;this.age = age;this.stupid = stupid;}public String getName() {return name;}public int getAge() {return age;}public boolean isStupid() {return stupid;}
}

没有什么不寻常的。 现在让我们定义合同:

PersonProcessingService.java

package com.blogspot.toomuchcoding.person.service;import com.blogspot.toomuchcoding.person.domain.Person;public interface PersonProcessingService {boolean isApplicableFor(Person person);String process(Person person);
}

如前提条件中所述,PersonProcessingService的每个实现都必须定义合同的两点:

  1. 是否适用于当前人员
  2. 它如何处理一个人。

现在,让我们看一下我们拥有的一些处理器-由于它毫无意义,因此我不会在此处发布代码-您可以稍后在Github或Bitbucket上查看代码。 我们有以下@Component注释的PersonProcessingService实现:

  • AgePersonProcessingService
    • 如果某人的年龄大于或等于18,则适用
  • IntelligencePersonProcessingService
    • 适用于某人是愚蠢的人
  • NamePersonProcessingService
    • 如果某人有名字,则适用

逻辑很简单。 现在,我们的PersonProcessingServices容器将要针对处理器上的给定Person进行迭代,检查当前处理器是否适用(过滤器),如果是这种情况,则将响应处理Person的结果字符串添加到响应列表中(映射–将Person转换为String的函数),并最终以逗号将这些响应合并(减少)。 让我们检查一下它是如何完成的:

PersonProcessingServiceContainer.java

package com.blogspot.toomuchcoding.person.service;import java.util.ArrayList;
import java.util.List;import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;import com.blogspot.toomuchcoding.person.domain.Person;@Component
@Primary
class PersonProcessingServiceContainer implements PersonProcessingService {private static final Logger LOGGER = LoggerFactory.getLogger(PersonProcessingServiceContainer.class);@Autowiredprivate List<PersonProcessingService> personProcessingServices = new ArrayList<PersonProcessingService>();@Overridepublic boolean isApplicableFor(Person person) {return person != null;}@Overridepublic String process(Person person) {List<String> output = new ArrayList<String>();for(PersonProcessingService personProcessingService : personProcessingServices){if(personProcessingService.isApplicableFor(person)){output.add(personProcessingService.process(person));}}String result = StringUtils.join(output, ",");LOGGER.info(result);return result;}public List<PersonProcessingService> getPersonProcessingServices() {return personProcessingServices;}
}

如您所见,我们有一个用@Primary注释的容器,这意味着如果必须注入PersonProcessingService的实现,则Spring将选择要注入的PersonProcessingServiceContainer。 很棒的事情是,我们有一个自动连接的PersonProcessingServices列表,这意味着该接口的所有其他实现都将在那里自动连接(容器不会自动将其自身连接到该列表!)。

现在,让我们检查一下Spock测试 ,这些测试证明我没有在说谎。 如果您尚未在项目中使用Spock,则应立即将其移动。

PersonProcessingServiceContainerIntegrationSpec.groovy

package com.blogspot.toomuchcoding.person.service
import com.blogspot.toomuchcoding.configuration.SpringConfiguration
import com.blogspot.toomuchcoding.person.domain.Person
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
import spock.lang.Unrollimport static org.hamcrest.CoreMatchers.notNullValue@ContextConfiguration(classes = [SpringConfiguration])
class PersonProcessingServiceContainerIntegrationSpec extends Specification {@AutowiredPersonProcessingService personProcessingServicedef "should autowire container even though there are many implementations of service"(){       expect: personProcessingService instanceof PersonProcessingServiceContainer}def "the autowired container should not have itself in the list of autowired services"(){       expect: personProcessingService instanceof PersonProcessingServiceContainerand:!(personProcessingService as PersonProcessingServiceContainer).personProcessingServices.findResult {it instanceof PersonProcessingServiceContainer}}def "should not be applicable for processing if a person doesn't exist"(){given:Person person = nullexpect:!personProcessingService.isApplicableFor(person)}def "should return an empty result for a person not applicable for anything"(){given:Person person = new Person("", 17, false)when:def result = personProcessingService.process(person)then:result notNullValue()result.isEmpty()}@Unroll("For name [#name], age [#age] and being stupid [#stupid] the result should contain keywords #keywords")def "should perform different processing depending on input"(){given:Person person = new Person(name, age, stupid)when:def result = personProcessingService.process(person)        then:keywords.every {result.contains(it)    }where:name  | age | stupid || keywords"jan" | 20  | true   || ['NAME', 'AGE', 'STUPID']""    | 20  | true   || ['AGE', 'STUPID']""    | 20  | false  || ['AGE']null  | 17  | true   || ['STUPID']"jan" | 17  | true   || ['NAME']}
}

测试非常简单:

  1. 我们证明自动接线字段实际上是我们的容器– PersonProcessingServiceContainer。
  2. 然后,我们证明在PersonProcessingService的自动装配实现的集合中找不到对象,该对象属于PersonProcessingServiceContainer类型
  3. 在接下来的两个测试中,我们证明处理器背后的逻辑正在运行
  4. 最后但并非最不重要的一点是Spock最出色的– where子句,它使我们能够创建漂亮的参数化测试。

每个模块的功能

想象一下您在核心模块中定义了接口的实现的情况。

@Component
class CoreModuleClass implements SomeInterface {
...
}

如果您在与核心模块有依赖性的其他模块中决定不想使用此CoreModuleClass并希望在SomeInterface自动连线的任何地方都具有一些自定义逻辑该怎么办? 好吧–使用@Primary!

@Component
@Primary
class CountryModuleClass implements SomeInterface {
...
}

通过这种方式,您可以确保必须自动装配SomeInterface的位置将是您的CountryModuleClass,将其插入到该字段中。

结论

在这篇文章中,您可以看到如何

  • 使用@Primary批注创建类似接口实现的复合容器
  • 使用@Primary批注提供接口的每个模块实现,在自动装配方面,该实现将优先于其他@Components
  • 编写出色的Spock测试:)

代码

您可以在Too Much Coding的Github存储库或Too Much Coding的Bitbucket存储库中找到此处提供的代码。

参考:来自我们的JCG合作伙伴 Marcin Grzejszczak(位于Blog上)的 Spring @Primary注释 适用于编码成瘾者博客。

翻译自: https://www.javacodegeeks.com/2013/12/springs-primary-annotation-in-action.html

spring 注释的作用

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

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

相关文章

导数与函数极值

http://wuli.wiki//online/DerMax.html

【渝粤题库】国家开放大学2021春1032成本管理题目

教育 教育 试卷代号&#xff1a; 1032 2021年春季学期期末统一考试 成本管理 试题 2021年7月 一、单项选择题&#xff08;本类题共20分&#xff0c;每小题2分&#xff09; 1.交互分配法一般在( )分配中使用。 A.直接材料费用 B.辅助生产费用 C.直接工资 D.在产品成本 2.采用品…

5g消息服务器,《5G消息白皮书》内容解读:5G消息是什么服务?

中国移动、中国电信、中国联通联合举行线上发布会&#xff0c;共同发布《5G消息白皮书》。《白皮书》阐述了5G消息的核心理念&#xff0c;明确了相关业务功能及技术需求&#xff0c;提出了对5G消息生态建设的若干构想。据悉&#xff0c;《5G消息白皮书》详细阐述了“5G消息业务…

JDK Bug系统浪费时间

当我在OpenJDK jdk-dev邮件列表中看到Jesper Wilhelmsson的消息标题“ Introducing time浪费者 ”时&#xff0c;想到了消息的可能内容的几种可能性。 在阅读该链接与单击该链接后出现该消息之间的第二个左右时间内 &#xff0c;我想知道该消息是否与以下主题之一有关&#xff…

驻点、极值点、拐点间的区别和联系

一、极值点与驻点的“纠缠” 我们可以从以下三点去理解它们的区别与联系&#xff1a; 二、拐点和另两者的“牵扯” https://zhuanlan.zhihu.com/p/95782395

【渝粤题库】国家开放大学2021春1050金融理论前沿课题题目

教育 教育 试卷代号&#xff1a; 1050 2021年春季学期期末统一考试 金融理论前沿课题 试题&#xff08;开卷&#xff09; 2021年7月 一、名词解释&#xff08;每小题5分&#xff0c;共15分&#xff09; 1.骆驼评级体系&#xff1a; 2.经济数据偏差&#xff1a; 3.核心通货膨胀…

【渝粤题库】国家开放大学2021春1070组织行为学题目

教育 教育 试卷代号&#xff1a;1070 2021年春季学期期末统一考试 组织行为学 试题 2021年7月 注意事项 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考场。…

御龙在天手游怎么不显示服务器了,御龙在天手游进不去怎么办 闪退原因及解决办法...

御龙在天手游进不去怎么办&#xff1f;闪退原因及解决办法。御龙在天手游今天迎来了安卓平台的不删档不限号测试(游戏出现打不开的问题&#xff0c;下面就让小编为大家介绍一下出现这类问题的原因及解决办法吧&#xff01;1.服务器问题游戏早上10点左右公布了下载的地址&#x…

矩阵乘法和向量乘法

1. 矩阵乘法 2.向量乘法 https://zhuanlan.zhihu.com/p/79760117

【渝粤题库】国家开放大学2021春1080工程数学(本)题目

教育 教育 试卷代号&#xff1a; 1080 2021年春季学期期末统一考试 工程数学&#xff08;本&#xff09; 试题 2021年7月 一、单项选择题&#xff08;每小题3分&#xff0c;共15分&#xff09; 1.设方阵可逆&#xff0c;则下列命题中不正确的是( ). A. B.线性方程组必有非零解…

怪物猎人服务器维护时间,怪物猎人云服务器

怪物猎人云服务器 内容精选换一换云耀云服务器适用于对CPU、内存、硬盘空间和带宽无特殊要求&#xff0c;服务一般只需要部署在一台或少量的服务器上&#xff0c;一次投入成本少&#xff0c;后期维护成本低的场景。例如网站开发&#xff0c;Web应用。推荐使用云耀云服务器&…

【渝粤题库】国家开放大学2021春1107传感器与测试技术题目

教育 教育 试卷代号&#xff1a;1107 2021年春季学期期末统一考试 传感器与测试技术 试题 2021年7月 一、单项选择题&#xff08;12小题&#xff0c;每小题3分&#xff0c;共36分&#xff09; 1.电阻应变片的绝缘电阻是指已粘贴的应变片的&#xff08; &#xff09;间的电阻值…

国家开放大学2021春1133文献检索题目

教育 试卷代号&#xff1a; 1133 2021年春季学期期末统一考试 文献检索 试题&#xff08;开卷&#xff09; 2021年7月 一、单项选择题&#xff08;每小题2分&#xff0c;共40分&#xff0c;每小题仅有一项答案正确&#xff0c;请将正确答案的序号填在括号内&#xff09; 1.以下…

Vaadin Flow –奇妙的鹿

您可能知道&#xff0c;Vaadin是Java上最受欢迎的Web框架之一&#xff1a; https://zeroturnaround.com/rebellabs/java-web-frameworks-index-by-rebellabs/ https://javapipe.com/hosting/blog/best-java-web-frameworks/ 最近发布了该Web UI开发框架的新版本– Vaadin 10…

国家开放大学2021春1171科学与技术题目

试卷代号&#xff1a; 1171 2021年春季学期期末统一考试 科学与技术 试题&#xff08;开卷&#xff09; 2021年7月 一、选择题&#xff08;每题4分&#xff0c;共20分&#xff09; 1.原子由( )和原子核组成。 A.粒子 B.质子 C.电子 D.夸克 2.三大合成高分子材料是( )。 A.塑料合…

转置与变换(Transposes and Permutation)

1. 转置(Transposes) 2. Inner Product 3. 对称(symmetric) 4. RTRR^TRRTR 5. Permutation 6.PALU 7. Conclusion 总结一下就是转置和对称的相互关系&#xff0c;以及其一些特性&#xff0c;矩阵中元素的位置变换成为了本文重点。 https://face2ai.com/math-linear-algebra-c…

国家开放大学2021春1194建设监理题目

试卷代号&#xff1a; 1194 2021年春季学期期末统一考试 建设监理 试题 2021年7月 一、单项选择题&#xff08;每小题2分&#xff0c;共40分。每题的备选项中&#xff0c;只有一个最符合题意&#xff09; 1.建设监理的服务对象是( )。 A.工程监理单位 B.建设单位 C.设计单位 D.…

排名前20位的在线编程课程,可促进您的职业发展

您是否想知道用时间和金钱可以进行的最佳投资是什么&#xff1f; 知识 作为软件开发人员&#xff0c;您应该不断学习新技能。 这是发展您的职业并享受奖励&#xff08;金钱&#xff0c;情感等&#xff09;的最佳方法。 朝着这个方向前进&#xff0c;您应该阅读书籍&#xff…

国家开放大学2021春1257混凝土结构设计原理题目

试卷代号&#xff1a; 1257 2021年春季学期期末统一考试 混凝土结构设计原理 试题 2021年7月 一、单项选择题&#xff08;每小题2分&#xff0c;共30分&#xff0c;在每小题列出的四个选项中只有一个选项是符合题目要求的&#xff0c;请将正确选项前的字母填在题目中的括号内&a…

线性代数

一、线性方程组 三、矩阵、向量中元素的符号 四、矩阵中行向量、列向量 五、行向量 列向量 (向量内积) 六、列向量 行向量(向量外积) 七、矩阵 列向量 (按行写矩阵) 八、矩阵 列向量 (按列写矩阵) 九、行向量 矩阵 &#xff08;矩阵按列写&#xff09; 十、行向量 矩阵 &…