mysql8.0_使用Java 8.0进行类型安全的依赖注入

mysql8.0

mysql8.0

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

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

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

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

因此,基于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()方法,该方法提供了一个添加新ObjectDefinitions的钩子。

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

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 ependancynjectionÇontainer。

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

mysql8.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值