千家信息网

Java的DI依赖注入示例分析

发表于:2024-10-23 作者:千家信息网编辑
千家信息网最后更新 2024年10月23日,本篇内容主要讲解"Java的DI依赖注入示例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java的DI依赖注入示例分析"吧!依赖注入 (DI) 是一
千家信息网最后更新 2024年10月23日Java的DI依赖注入示例分析

本篇内容主要讲解"Java的DI依赖注入示例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java的DI依赖注入示例分析"吧!

依赖注入 (DI) 是一种让类从外部接收其依赖的技术。如果类 A 使用类 B,则类 A 依赖于类 B,而 B 是 A 的依赖项。

以下示例显示了 Java 中的依赖项和 DI 是什么。在第一个示例中,A 类依赖于 B 类,因为 B 是 A 的成员。A 和 B 是紧密耦合的。每当 B 改变时,A 就必须改变。这种情况称为硬依赖。

// hard dependencyclass A{    private B b;     public A(){        this.b = new B();    }     ...}

在第二个例子中,A 仍然依赖于 B,但依赖不是硬编码的。它通过在构造函数中使用参数来解耦。如果 A 需要 B 的不同实现,A 可以使用 B 的不同实现来构造实例。这导致了 DI 的一个关键特性:被注入的类应该是一个抽象接口,以便可以将不同的实现注入到 A。如果 B 的实现只有一个,则不需要进行 DI。

// dependency injection through constructorclass A{    private B b;     public A(B b){        this.b = b;    }     ...}

使用依赖注入的好处

DI 的一个示例用途是数据访问对象 (DAO)。执行 CRUD 操作的类通常需要访问数据库。使用 DI 向应用程序注入 DAO 将应用程序层与数据持久层解耦。如果底层数据库发生变化,只要这些 DAO 实现相同的接口,应用程序类就可以更改为不同的 DAO。另一个好处是使单元测试更容易。单元测试可以使用伪造的(硬编码或内存中的)DAO 来测试应用程序逻辑,而无需担心底层数据库访问。

DI 是流行的 Java 框架(如 Spring 和 Hibernate)中使用的一项关键技术。框架不是手动创建 B 对象并将其传递给 A 的构造函数,而是使用反射来创建依赖对象并根据配置将它们注入到适当的位置。

一个展示依赖注入的简单例子

下面是一个简单的例子来说明使用框架时 DI 的样子以及使用 DI 的两个好处。我使用 Guice 框架,但其他框架在幕后以相同的方式工作。

假设我们有一台计算机,它有很多部分协同工作,例如 CPU、内存等。 CPU 中有两种方法。

public interface CPU {    public void start();    public int getUsage();}

CPU 可以是 Intel,

public class Intel implements CPU{    @Override    public void start() {        System.out.println("Intel is started.");    }     @Override    public int getUsage() {        return new Random().nextInt(100);    }}

或 AMD。

public class Amd implements CPU {    @Override    public void start() {        System.out.print("Amd is started");    }     @Override    public int getUsage() {        return new Random().nextInt(100);    }}

在 Guice 中,通过构造函数注入依赖就像添加 @Inject 注释一样简单。

public class Computer {    private CPU cpu;     @Inject    Computer(CPU cpu) {        this.cpu = cpu;    }     public void start() {        cpu.start();        // start other parts    }     public boolean isStatusOk() {        //assuming this random        if (cpu.getUsage() > 50) {            return false;        }         // check other things, such as memory, hard drives.         return true;    }     public static void main(String[] args) {        Injector injector = Guice.createInjector(new BasicModule());        Computer computer = injector.getInstance(Computer.class);        computer.start();        System.out.println("Status:" + (computer.isStatusOk() ? "OK" : "Not OK"));    }}

Guice 使用模块来配置注入。在此示例中,当请求 CPU 时,模块将具体的 Intel 绑定到 CPU。

public class BasicModule extends AbstractModule {    @Override    protected void configure() {        bind(CPU.class).to(Intel.class);    }}

这样做的好处是显而易见的。计算机可以在需要时灵活地使用其他类型的 CPU。此外,如果 CPU 依赖于另一个类,例如 Cache 或 Clock,我们可以使用相同的方式注入依赖项,而无需耦合这些类。

关于第二个好处--让单元测试更简单,我们可以做一个简单的单元测试来测试 isStatusOk() 方法。在实际情况下,CPU 使用率可以是基于实际使用情况的随机数。如果我们想把测试的重点放在方法的其他部分,我们可以模拟 CPU 的使用情况,假设 CPU 使用率没问题,然后测试其他部分。

public class ComputerTest {    @Test    public void testIsStatusOk(){        CPU cpu = mock(CPU.class);        // mock cpu usage, so we can focus on testing other part        when(cpu.getUsage()).thenReturn(10);        assertTrue(new Computer(cpu).isStatusOk());    }}

总之,DI 是为了分离对象创建和使用的关注点。DI 解耦类依赖并使单元测试更容易。

到此,相信大家对"Java的DI依赖注入示例分析"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0