简体   繁体   English

在不依赖框架的情况下理解java中的依赖注入。 在纯Java代码中它是什么样的?

[英]Understanding dependency injection in java without relying on a framework. What does it look like in pure java code?

I'm learning about the Spring framework for Java. 我正在学习Java的Spring框架。 Its all about dependency injection. 这完全是关于依赖注入。 Is there blog or some resource or example I can use to understand RAW Dependency injection? 是否有博客或某些资源或示例我可以用来理解RAW依赖注入? In other words, without annotations or xml or any container. 换句话说,没有注释或xml或任何容器。 What does Dependency Injection look like in pure java code? 在纯Java代码中,依赖注入是什么样的?

Thank you in advance! 先感谢您!

The dependency injection in pure Java is a really simple concept. 纯Java中的依赖注入是一个非常简单的概念。 Suppose you have a classes A and B as follows: 假设你有一个AB类如下:

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

Class A internally instantiates class B and so B becomes A 's dependency . A内部实例化类BB变得A依赖性 If you want to test A in isolation, you cannot do it (because it depends on B ). 如果要单独测试A ,则不能这样做(因为它取决于B )。 If you want to provide A with a different implementation of B , you have to edit the source code of A , which is not always possible or just not the best idea. 如果你想为A提供不同的B实现,你必须编辑A的源代码,这并不总是可行或者不是最好的想法。

Instead consider injecting a dependency through constructor (it is one of the methods you can choose with Spring). 相反,请考虑通过构造函数注入依赖项 (它是您可以使用Spring选择的方法之一)。 You create a public constructor for A , which takes a B as an argument: 您为A创建一个公共构造函数,它将B作为参数:

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

Now, instead of constructing the object inside class, you give it ( inject ) a parameter in an outside code. 现在,不是在类中构造对象,而是在外部代码中给它( 注入 )一个参数。 The advantage of this is that you can pass a different implementation of B , or a mock for testing: 这样做的好处是你可以传递不同的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

If B and B2 implement the same interface or B2 extends B , you can use them interchangeably depending on your needs. 如果BB2实现相同的接口或B2扩展B ,您可以根据需要互换使用它们。 This provides a great deal of flexibility. 这提供了很大的灵活性。 This is basically how dependency injection without a DI container works. 这基本上是没有DI容器的依赖注入的工作原理。 Spring might be an overkill for small applications, but the basic idea is really simple, it is a good practice and you should definitely use it. Spring可能对小型应用程序来说太过分了,但基本的想法非常简单,这是一个很好的做法,你绝对应该使用它。

A good resource to learn basics about Spring (and other things) is Java Brains . Java Brains是学习Spring(和其他东西)基础知识的好资源。

It would look like this (assuming all beans are prototype scope): 它看起来像这样(假设所有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");
    }
}

Of course, enhanced by reflection and other libraries like cglib to create proxy classes on the fly. 当然,通过反射和其他库(如cglib)增强,可以动态创建代理类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM