使用Java 8.0进行类型安全的依赖注入

所以有时我真的很想念旧学校的依赖注入。 当Spring仍然“轻量级”时,我们很高兴地用“ 一天学习 ” Spring bean xml配置在application.xml文件中配置了所有bean。 缺点当然是类型安全性的损失。 我可以想到很多测试用例,它们的唯一目的是引导Spring配置文件,并只是看看ApplicationContext是否由于接线错误和所包含的bean xml配置文件的正确解析而启动而不会引起麻烦。

我可能是少数,但我从未喜欢过Spring Schema配置。 在我看来,配置有点像配置。


需要注意的是,您必须为所有这些注释导入库。 我喜欢注释,但是将所有DI信息放在一个中央位置是一个很好的情况,这样您就可以实际看到您的应用程序是如何挂在一起的。 最后,有时您需要创建无法注释的托管对象。

Java Spring配置通过编译时安全性使事情变得更好,但是我不得不重新考虑我执行大量接线的方式,因为当我丢失了一些懒惰的评估时,我不得不小心地进行接线。当ApplicationContext启动时,作为Java代码的Spring上下文将立即评估。

因此,基于Java的DI很好,但是如何使用Java 8.0进行改进呢?

套用Lambda Hammer

正确,所以这是开始在Java 8.0中应用新锤子的文章的一部分: Lambdas 。

首先,Lambda提供了一种安全的方式来推迟执行直到需要时。

因此,让我们首先创建一个称为“ ObjectDefinition”的包装对象,该对象的工作是定义如何创建对象并使用各种值进行连接。 它通过实例化要创建的类和对象来工作(在这种情况下,我们有一个名为“ MyObject ”的类)。 我们还为它提供了映射到特定值的java.util.function.BiConsumer接口的列表。 该列表将用于执行在对象上设置值的实际任务。

然后,ObjectDefintion使用正反射实例化对象,然后运行BiConsumer接口列表,传递具体对象的实例和映射的值。

假设我们为ObjectDefinition提供了流畅的DSL,我们可以通过添加set()方法来定义对象,该方法采用BiConsumer和要设置的值并填充BiConsumer列表,如下所示:

MyObject result = new ObjectDefinition() .type(MyObject.class).set((myObject, value)-> myObject.setA(value), "hello world").set((myObject, value)-> myObject.setB(value), "hallo welt").create();

create()方法仅实例化MyObject实例,然后遍历BiConsumers列表,并通过映射值调用它们。

(好金田)

现在,Java 8.0中的另一个有趣的功能是方法引用,该功能是编译器将方法包装在功能接口中的功能,条件是该方法可以映射到该功能接口的签名。

方法引用允许您映射到对象的任意实例,前提是该方法的第一个参数是该实例值,且后续参数与其参数列表匹配。

这使我们可以将BiConsumer映射到setter,其中第一个参数是目标实例,第二个参数是传递给setter的值:

MyObject result = new ObjectDefinition().type(MyObject.class).set(MyObject::setA, "hello world").set(MyObject::setB, "hallo welt").create();

方法引用提供了一个有趣的功能,因为它提供了一种以完全类型安全的方式将引用传递给方法的方法。 所有示例都需要设置正确的类型和值,并且setter方法需要与该类型相对应。

现在是集装箱时间

因此,现在我们有了一个不错的用于构建对象的小DSL,但是如何将其粘贴到容器中并允许ObjectDefinition注入对其他值的引用呢?

好吧,假设我们有这个容器,它方便地提供了一个build()方法,该方法提供了一个添加新ObjectDefinition的钩子。

现在,我们有了一个容器,可以用来在该容器中注入不同的对象:

Container container = create((builder) -> {builder.define(MyObject.class).set(MyObject::setA, "hello world");});String myString = container.get(MyObject.class);

我们的Container对象具有define()方法,该方法创建ObjectDefinition的实例,然后该实例用于定义如何创建对象。

但是依赖项呢?

如果不能注入依赖项,则依赖注入是没有乐趣的,但是由于有了容器,我们现在可以引用容器中的其他对象。

为此,我们将inject()方法添加到我们的ObjectDefinition类型中,然后可以使用该类型来引用容器中的另一个对象:

Container container = create((builder) -> {builder.define(String.class).args("hello world");builder.define(MyObject.class).inject(MyObject::setA,String.class);});MyObject myString = container.get(MyObject.class);

在此示例中,我们映射了另一个String类型的对象这里的args()方法是可以将值映射到对象的构造函数的方法)。 然后,我们调用inject()方法注入此String。

生命周期。

我们可以使用Lambda和方法引用的相同方法来管理容器中对象的生命周期。

假设我们要在设置所有值之后运行初始化方法,我们只需添加一个新的Functional接口,然后在设置所有值之后调用该接口。

在这里,我们使用java.util.function.Consumer接口,其中参数是我们要调用初始化代码的实例。

Container container = create((builder) -> {builder.define(MyObject.class).set(MyObject::setA,"hello world").initWith(MyObject::start);});MyObject myString = container.get(MyObject.class);

在此示例中,我们向MyObject类添加了一个start()方法。 然后将其作为消费者通过initWith()方法传递给ObjectDefinition。

另一个依赖注入容器

因此,所有这些技术(和更多)被包括在YADI集装箱,它表示Y诺特尔d ependancy njectionÇontainer。

  • 可以在Github上找到该代码,网址为https://github.com/jexenberger/yadi 。 并根据Apache许可获得许可。

翻译自: https://www.javacodegeeks.com/2014/06/type-safe-dependency-injection-using-java-8-0.html

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

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

相关文章

mysql从库执行delete停止_MySQL主库大表执行delete语句,Ctrl+C具体发生了什么分析...

MySQL主库大表执行delete语句,CtrlC具体发生了什么分析1、查看表结构localhost.qt>show create table doctor_stats_backup\G*************************** 1. row ***************************Table: doctor_stats_backupCreate Table: CREATE TABLE doctor_stat…

python打开火狐浏览器打不开网页_PHP让指定网页只能在微信内置浏览器打开 附代码...

有时候,有些网页不方便在电脑或者手机QQ打开,比如:想创建一个微信活动页面,在电脑或者QQ打开会导致某些功能失效,页面错版等情况,为了避免出现这种情况,其实我们只需让它只能在微信打开就可以了…

我的世界服务器设置op显示,我的世界设置op权限 | 手游网游页游攻略大全

发布时间:2017-08-19导读:不少我的世界腐竹都会收留一些OP帮助自己管理服务器,那么如果想取消OP的权限该如何操作呢?下面小编就来教教大家如何取消OP权限. 问:我的世界如何取消OP权限? 答:/deop 用户名,就是取消OP,/op 用户名 ...标签:我的世界 问答帮…

mysql 从库重新同步_mysql从库删除数据重新同步

1、查看slave状态show slave status\G2、停止slave状态,清除从库主从信息stop slave;reset slave;reset master;3、将从库已同步主库数据库删除DROP DATATBASE DBNAME;4、备份主数据库数据reset master; //先重置主库,再导出mysqldump -uuser…

Mockito“ thenReturn” vs Mockito“ thenAnswer”

在编写代码测试用例时,Mockito是开发人员最常见的选择之一。 然后我们面对的问题是,如何使用Mockito的thenReturn()和thenAnswer()方法? 如果您也面临这个问题,请不要担心每个人都面…

python turtle画彩虹的代码_如何用python海龟库画彩虹

python生成的彩虹效果,大家可以参考:使用的python版本:3.7.0 ,以下为源代码:# rainbow.py from turtle import * from random import * def HSB2RGB(hues): hues hues * 3.59 #100转成359范围 rgb [0.0,0.0,0.0] i …

vsphere虚拟克隆虚拟服务器,vSphere实战攻略2:虚拟机模板与克隆

【IT168 专稿】 (接上篇)"模板"是VMware为虚拟机提供的一项功能,可以让用户在其中一台虚拟机的基础上,很方便的"派生"或"克隆"出多台虚拟机,这减轻了管理员的负担。1.1 创建模板虚拟机在使用模板之前&#xff…

mysql parameter_C#MySqlParameter问题

(int)faultsGroup是0或1但我总是得到这个错误:列’FaultGroup’不能为null有人告诉我为什么吗?语法看起来不错.MySqlCommand cmdAdd new MySqlCommand("INSERT INTO Faults (" " FaultGroup, Text, Date, IP" ") VALUES (&quo…

python数据写入表格生成图片_python带表格图片生成封装

#!/usr/bin/python3#-*- coding: utf-8 -*-## author:qianqiu from prettytable importPrettyTablefrom PIL importImage, ImageDraw, ImageFontdef create_table_img(data,img_name, **kwargs):img_name 图片名称 D:/project/pythonwork/12306/t.png 或 t.png data 表格内容&a…

java ee maven_针对新手的Java EE7和Maven项目–第6部分

java ee maven从前面的部分恢复 第1 部分 , 第2 部分 , 第3 部分 , 第4 部分 , 第5部分 在上一篇文章(第5部分)中,我们发现了如何使用Arquillian(我们的EJB服务)进行单元…

mysql数据库优化教程_mysql数据库索引优化学习教程

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。拿汉语字典的目录页(索引)打比方&#x…

windows系统git服务器启动,windowsServer服务器上搭建GIt服务器

十年河东,十年河西,莫欺少年穷学无止境,精益求精摸索了一天,终于把服务器端Git搭建完毕。记录下来,省的以后踩坑。如下:在官网搜索框中输入:download 搜索下载型选择为Java选择开发版然后下载下…

python程序设计题答案_《Python程序设计》习题与答案

第3章 选择结构与循环结构 3.1 分析逻辑运算符“or”的短路求值特性。 答: 假设有表达式“表达式1 or 表达式2”,如果表达式1的值等价于True,那么无论表达式2的值是什么,整个表达式的值总是等价于True。因此,不需要再计…

Linux普通玩家,熟悉这些高频命令就行了

回想当时入门Linux时抱着鸟叔的私房菜啃,看了没几页就放弃了 如果主要从事算法相关工作,其实高频使用的命令就那么些,一起看看吧 用户相关 id – 显示用户的详细信息(uid、gid和group)last – 列出有关最近登录的信…

如何在黄瓜中进行后端测试

黄瓜是一种规范语言的执行框架。 它并不是要成为测试语言,而是用于创建测试自动化。 黄瓜最适合出现一些现实世界中的参与者互动并取得某种成果的情况。 当可以从用户的角度编写它时,它特别有用。 Given Sarah is a premium club member When Sarah lo…

mysql权限层级体系_MySQL权限体系介绍

官方手册:https://dev.mysql.com/doc/refman/5.7/en/privileges-provided.htmlMySQL是一个多用户的数据库,MySQL的用户可以分为两大类:(1)超级管理员用户(root),拥有全部权限(2)普通用户,由root创建,普通用…

云服务器 生物信息学,云服务器 生物信息学

云服务器 生物信息学 内容精选换一换挂载有NVMe SSD盘的Linux弹性云服务器(如P1型云服务器)发生故障时,需联系管理员通过异地重建的方式进行恢复,新建故障弹性云服务器。如果故障弹性云服务器在/etc/fstab中设置了NVMe SSD盘的开机自动挂载功能&#xff…

python图像转字符画_python图像处理-字符画风格图片

前言 字符画图片,顾名思义就是由一个个字符组成的图片,下面这张图片很容易帮助你理解,如果我们可以将字符排列好,让他看上去像一个物体的形状,那么最后再将它输出保存为一张图片就可以实现了。下面的这些形状同样可以使…

在mybatis用mysql的代码块_mybatis plus与mysql分库组件mycat的结合

之前的文章简单介绍了一下mybatis plus:《使用Mybatis-plus代替原生Mybatis》。截止目前在项目中使用了一段时间的mybatis plus,再也没有写过sql,都用mp的Wrapper封装查询条件了。这里先简单介绍一下mp的用法(抱歉,上一篇里面讲得…

响应服务器535.5.7.0AUTH,javax.mail.AuthenticationFailedException:535 5.7.3无法发送邮件

我遇到了错误javax.mail.AuthenticationFailedException:535 5.7.3尝试发送电子邮件时的身份验证。我尝试使用两个不同的电子邮件帐户。一个使用Office365服务器详细信息,另一个使用Gmail服务器详细信息。在两种情况下,我都会遇到相同的错误。…