【问题标题】:Understanding dependency injection in java without relying on a framework. What does it look like in pure java code?在不依赖框架的情况下理解 Java 中的依赖注入。它在纯 java 代码中是什么样子的?
【发布时间】:2014-06-29 05:31:39
【问题描述】:

我正在学习 Java 的 Spring 框架。这都是关于依赖注入的。是否有博客或一些资源或示例可以用来理解 RAW 依赖注入?换句话说,没有注释或 xml 或任何容器。纯Java代码中的依赖注入是什么样的?

提前谢谢你!

【问题讨论】:

  • ... 将接口的实现传递给使用它们的类。不要把事情复杂化——这意味着类被赋予了事物的实现,而不是类决定使用什么实现。
  • [Here][1] 是了解依赖注入的 stacoverflow 链接:[1]: stackoverflow.com/questions/3334578/…

标签: java spring oop dependency-injection


【解决方案1】:

看起来像这样(假设所有 bean 都是原型范围):

class BeanToBeInjected {
}

class BeanThatNeedsInjection {
    BeanToBeInjected beanToBeInjected;
    public void setBeanToBeInjected(BeanToBeInjected beanToBeInjected) {
        this.beanToBeInjected = beanToBeInjected;
    }
}

class BeanFactory {
    public Object createBean(String id) {
        if("beanThatNeedsInjection".equals(id) {
            BeanThatNeedsInjection beanThatNeedsInjection = new BeanThatNeedsInjection();
            beanThatNeedsInjection.setBeanToBeInjected(new BeanToBeInjected());
            return beanThatNeedsInjection;
        }
        return null;
    }
}

class MyService {
    public void service() {
        BeanThatNeedsInjection beanThatNeedsInjection =
            new BeanFactory().createBean("beanThatNeedsInjection");
    }
}

当然,通过反射和其他库(如 cglib)增强了动态创建代理类。

【讨论】:

  • 谢谢路易吉。在示例中如此清楚地展示了!什么是“通过使用反射和其他库(如 cglib)来增强”?
  • @TazMan 因为您将有很多类并且您不确定要注入哪些字段。为此,您可以使用反射使其更通用。此外,为了为类创建代理以添加操作的事务管理等功能,您需要动态创建类及其实例,而 cglib 可帮助您实现该目的。跨度>
【解决方案2】:

纯 Java 中的依赖注入是一个非常简单的概念。假设您有一个类AB,如下所示:

public class A{
    private B instanceOfB = new B();
    public method doSomething(){
        // does something involving B
    }
}

A 类在内部实例化B 类,因此B 成为A依赖关系。如果你想单独测试A,你不能这样做(因为它取决于B)。如果您想为A 提供B 的不同实现,则必须编辑A 的源代码,这并不总是可行或不是最好的主意。

请考虑通过构造函数注入依赖项(这是您可以使用 Spring 选择的方法之一)。您为A 创建了一个公共构造函数,它将B 作为参数:

class A{
    private B instanceOfB;
    public A(B instanceOfB){
        this.instanceOfB = instanceOfB;
    }
    public method doSomething(){
        // does something involving B
    }
}

现在,不是在类中构造对象,而是在外部代码中给它(inject)一个参数。这样做的好处是您可以传递B 的不同实现,或模拟进行测试:

class B{ // whatever }
class B2 extends B{ // whatever }

A anInstanceOfA = new A(new B()); // this is ok, A will internally use B
A anotherInstanceOfA = new A(new B2()); // and this instance will use B2 instead

如果BB2 实现相同的接口或B2 扩展B,您可以根据需要互换使用它们。这提供了很大的灵活性。这基本上就是没有 DI 容器的依赖注入的工作原理。 Spring 对于小型应用程序来说可能有点过头了,但基本思想非常简单,这是一个很好的实践,你绝对应该使用它。

Java Brains 是学习 Spring(和其他东西)基础知识的好资源。

【讨论】:

    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 2014-11-23
    • 1970-01-01
    • 2021-01-07
    • 2011-05-16
    • 2015-10-12
    • 2014-09-06
    • 1970-01-01
    相关资源
    最近更新 更多