组件注入 # 注入的属性_注入域对象而不是基础结构组件

组件注入 # 注入的属性

依赖注入是Java(以及许多其他编程语言)中广泛使用的软件设计模式,用于实现控制反转 。 它提高了可重用性,可测试性,可维护性,并有助于构建松耦合的组件。 如今,依赖注入是将Java对象连接在一起的事实上的标准。

诸如Spring或Guice之类的各种Java框架可以帮助实现依赖注入。 从Java EE 6开始,还有一个正式的Java EE API用于依赖关系注入: 上下文和依赖关系注入 (CDI)。

我们使用依赖注入来注入服务,存储库,与域相关的组件,资源或配置值。 但是,以我的经验,依赖注入也可以用来注入域对象,这常常被忽略。

一个典型的例子是在Java许多应用程序中获取当前登录用户的方式。 通常,我们最终会向登录用户询问某些组件或服务。

此代码看起来可能类似于以下代码片段:

public class SomeComponent {@Injectprivate AuthService authService;public void workWithUser() {User loggedInUser = authService.getLoggedInUser();// do something with loggedInUser}
}

此处,将AuthService实例注入SomeComponent。 SomeComponent的方法现在使用AuthService对象来获取已登录用户的实例。

但是,除了注入AuthService之外,我们还可以将登录的用户直接注入SomeComponent。

可能看起来像这样:

public class SomeComponent {@Inject@LoggedInUserprivate User loggedInUser;public void workWithUser() {// do something with loggedInUser}
}

在这里,User对象直接注入SomeComponent中,不需要AuthService实例。 如果存在多个类型为User的(托管)bean,则使用自定义批注@LoggedInUser来避免冲突。

Spring和CDI都可以进行这种类型的注入(并且配置实际上非常相似)。 在下一节中,我们将看到如何使用Spring注入域对象。 在此之后,我将描述对CDI进行相同操作需要进行哪些更改。

使用Spring进行域对象注入

要注入上面示例中所示的域对象,我们只需要做两个小步骤。

首先,我们必须创建@LoggedInUser批注:

import java.lang.annotation.*;
import org.springframework.beans.factory.annotation.Qualifier;@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface LoggedInUser {}

请注意@Qualifier批注,它将@LoggedInUser转换为自定义限定符。 如果有多个相同类型的bean可用,Spring会使用限定符来避免冲突。

接下来,我们必须在我们的Spring配置中添加一个bean定义。 我们在这里使用Spring的Java配置,使用xml配置也可以完成。

@Configuration
public class Application {@Bean@LoggedInUser@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)public User getLoggedInUser() {// retrieve and return user object from server/database/session}
}

在getLoggedInUser()内部,我们必须检索并返回当前登录用户的实例(例如,通过从第一个片段中询问AuthService)。 使用@Scope,我们可以控制返回对象的范围。 最佳范围取决于域对象,并且在不同的域对象之间可能有所不同。 对于代表已登录用户的User对象, 请求会话范围将是有效的选择。 通过用@LoggedInUser注释getLoggedInUser(),我们告诉Spring应该在每次注入用户类型为@LoggedInUser的bean时使用此bean定义。

现在,我们可以将登录用户注入到其他组件中:

@Component
public class SomeComponent {@Autowired@LoggedInUserprivate User loggedInUser;...
}

在这个简单的示例中,实际上不需要限定符注释。 只要只有一个类型为User的bean定义可用,Spring可以按类型注入已登录的用户。 但是,在注入域对象时,很容易发生您具有相同类型的多个bean定义。 因此,使用附加的限定符注释是一个好主意。 限定符还可以使用其描述性名称充当文档(如果命名正确)。

简化Spring bean定义

注入许多域对象时,最终有可能在bean配置中一遍又一遍地重复作用域和代理配置。 在这种情况下,Spring注释可以在自定义注释上使用非常方便。 因此,我们可以简单地创建自己的@SessionScopedBean批注,以代替@Bean和@Scope:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public @interface SessionScopedBean {}

现在我们可以简化bean的定义:

@Configuration
public class Application {@LoggedInUser@SessionScopedBeanpublic User getLoggedInUser() {...}
}

Java EE和CDI

CDI的配置几乎相同。 唯一的区别是我们必须用javax.inject和CDI注释替换Spring注释。

因此,@LoggedInUser应该使用javax.inject.Qualifier而不是org.springframework.beans.factory.annotation.Qualifier进行注释(请参阅: 使用Qualifiers )。

Spring bean定义可以用CDI Producer方法代替。 可以使用适当的CDI范围注释代替@Scope。

在注入点,可以将Spring的@Autowired替换为@Inject。

请注意,Spring还支持javax.inject注释。 如果将javax.inject依赖项添加到Spring项目中,则还可以使用@Inject和@ javax.inject.Qualifier。 这样做实际上是一个好主意,因为它可以减少Java代码中的Spring依赖关系。

结论

我们可以使用自定义注释和作用域bean将域对象注入其他组件。 注入域对象可以使您的代码更易于阅读,并且可以导致更清晰的依赖关系。 如果仅注入AuthService来获取登录用户,则实际上取决于登录用户而不是AuthService。

不利的一面是,它使您的代码更牢固地依赖于依赖注入框架,该框架必须为您管理bean范围。 如果要保持在Dependency Injection容器之外使用类的能力,则可能会遇到问题。

哪种类型的域对象适合注入在很大程度上取决于您正在处理的应用程序。 好的候选对象是您经常使用的领域对象,并且不依赖于任何方法或请求参数。 当前登录的用户是可能通常适合注入的对象。

  • 您可以在GitHub上找到所示示例的源代码。

翻译自: https://www.javacodegeeks.com/2014/10/injecting-domain-objects-instead-of-infrastructure-components.html

组件注入 # 注入的属性

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

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

相关文章

docker $PWD路径_Docker安装Jenkins+Shell脚本自动化部署项目

本文同名博客老炮说Java:https://www.laopaojava.com/,每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料SentinelNacos 是微服务环境搭建必不可少的两个组件,这里给大家推荐一套微服务教程:SpringCloud微服务电商项目教程…

flyme Android7.0 root,手把手教你如何免ROOT卸载Flyme7系统自带APP

本教程需要使用adb,adb的全称为Android Debug bridge,就是起到调试桥的作用。借助adb工具,我们可以管理设备或手机模拟器的状态。本教程需要使用adb,adb的全称为Android Debug bridge,就是起到调试桥的作用。借助adb工…

C语言 -- 字符串中根据特定字符(串)分割

版权C语言字符串操作函数有很多,这里举出需要用到的,其他请自行查找。1、len strlen(p) ;//取字符串长度 原型:size_t strlen(const char *s); 功能:统计字符串string中字符的个数,字符串的长度在 size_t…

javaone_JavaOne 2014:会议与合同利益冲突

javaone杜克街咖啡馆,工程师可以在街上进行走廊交谈 。 与签约不兼容 我的第11届JavaOne会议(2004年至2014年为11 10 1)非常出色。 值得参加此活动并结识社区中所有的人。 现在,这里是绅士的,但 。 除了经济上的明显…

什么流读取MultipartFile_深入理解并运用Node中的IO模型流

在 NodeJs 中,流随处可见,读/写文件流,HTTP请求/返回流,stdin/stdout流。理解并运用好流会让你的Node更具力量。Streamlib/_stream_readable.jslib/_stream_writable.jslib/_stream_tranform.jslib/_stream_duplex.js流主要有可读…

android状态机是线程么,Java中的线程状态机 - java

有没有一种方法可以将线程保留在状态中等待更改?我的意思是,等一下事情发生了(更改var,调用方法等)。也许它需要使用事件监听器或同步的对象/方法。这样的状态机通常的方法statemachine example它使用一个do {..} while(true)循环&#xff0c…

C 线程的创建

前言线程创建很容易,直接调用std::thread,就创建一个新线程了。该线程拿到任务后立即开始执行。线程的创建者(父线程)必须管理创建的线程(子线程),应该等到子线程完成其任务或者让子线程从自己身…

apache karaf_未来是Apache Karaf上的微服务架构

apache karaf这是Jamie Goodyear的客座博客文章( 博客 , icbts )。 他是Savoir Technologies的开源倡导者,Apache开发人员和计算机系统分析师; 他为全球大型组织设计,批判和支持了体系结构。 他拥有纽芬兰…

AppScan api登录接口 postman_如何通过Postman调用EDI系统的API?

知行EDI系统主要是用来实现贸易双方的数据交换的过程,这个过程中,贸易双方往往需要根据国际通用的消息格式收发信息,我们称符合国际规范的消息文件为EDI报文,然而不同的公司会结合ERP的接口情况选择不同的集成方式,例如…

指针函数和函数指针

概述指针函数和函数指针是C语言里两个比较绕的概念。但是不仅面试题爱考,实际应用中也比较广泛。很多人因为搞不清这两个概念,干脆就避而远之,我刚接触C语言的时候对这两个概念也比较模糊,特别是当指针函数、函数指针、函数指针变…

android显示绘图动画,Android自定义View绘图实现渐隐动画

实现了一个有趣的小东西:使用自定义view绘图,一边画线,画出的线条渐渐变淡,直到消失。效果如下图所示:用属性动画或者渐变填充(shader)可以做到一笔一笔的变化,但要想一笔渐变(手指不抬起边画边渐隐)&#…

csrf spring_无状态Spring安全性第1部分:无状态CSRF保护

csrf spring如今,随着RESTful架构变得越来越标准,可能值得花一些时间重新考虑当前的安全方法。 在这一小系列博客文章中,我们将探索以无状态方式解决与Web相关的安全性问题的几种相对较新的方法。 这第一篇文章是关于保护您的网站免受跨站请求…

python网络编程项目_python网络编程详解

最近在看《UNIX网络编程 卷1》和《FREEBSD操作系统设计与实现》这两本书,我重点关注了TCP协议相关的内容,结合自己后台开发的经验,写下这篇文章,一方面是为了帮助有需要的人,更重要的是方便自己整理思路,加…

C - 指针总结

指针是什么?指针是一变量或函数的内存地址,是一个无符号整数,它是以系统寻址范围为取值范围,32位,4字节。指针变量:存放地址的变量。在C 中,指针变量只有有了明确的指向才有意义。指针类型int* …

android网络转圈,android基于dialog加载时转圈圈很好的demo

【实例简介】这是一个android基于dialog加载时转圈圈很好的完整demo,很适合新手学习,希望对有需要的朋友能得到帮助【实例截图】【核心代码】dialog_anim└── dialog_anim├── AndroidManifest.xml├── bin│ ├── AndroidManifest.xml│ ├…

spring期刊状态_无状态Spring安全性第2部分:无状态认证

spring期刊状态Spring Stateless Security系列的第二部分是关于以无状态方式探索身份验证的方法。 如果您错过了有关CSRF的第一部分,可以在这里找到。 因此,在谈论身份验证时,其全部内容就是让客户端以可验证的方式向服务器标识自己。 通常&…

分享10个值得关注的C语言开源项目

来源于网络,如有侵权,告知必删。

python3 x默认使用的编码_python3默认使用什么编码

python3默认编码为unicode,由str类型进行表示。二进制数据使用byte类型表示。 字符串通过编码转换成字节码,字节码通过解码成为字符串encode:str --> bytes(推荐学习:Python视频教程) decode&#xff1a…

html中写css代码,开发DIV CSS时 先写CSS代码还是先写HTML代码

相信良多LOVE用DIVCSS技术启示重构网页的爱好者友好,在起源学习DIVCSS的时分都邑想一个标题,想晓得DIVCSS妙手或有教育者在开发制作html页面的时刻,下场是先写html照样先写css?带着这…

象棋子 设计模式_通过设计国际象棋游戏了解策略模式

象棋子 设计模式今天,我们将借助一个示例来尝试了解策略模式。 我们将考虑的示例是国际象棋游戏。 这里的目的是解释策略模式,而不是构建全面的国际象棋游戏解决方案。 策略模式:策略模式被称为行为模式–用于管理对象之间的算法&#xff0…