Java中的Ioc / DI,支持接口解析

时间:2018-06-13 13:41:58

标签: java dependency-injection ioc-container

来自DotNet并使用" Unity"对于依赖注入和依赖性解析,我会这样:

public interface ILog
{
    void LogSomething(string msg);
}

public class MyLogger() : ILog
{
    public void LogSomething(string msg)
    {
        /* do something real here */
        Console.Writeline("I'm logging something: " + msg);
    }       
}


public interface IAnimal
{
    void MakeNoise();
}

public class Dog() : IAnimal
{
    private readonly ILog Logger;

    public Dog(ILog lgr)
    {
        this.Logger = lgr;
    }

    public void MakeNoise()
    {
        this.Logger.LogSomething("Bark Bark Bark");
    }       
}


public interface IVehicle
{
    int GetWheelCount();
}

public class Car() : IVehicle
{
    private readonly ILog Logger;

    public Car(ILog lgr)
    {
        this.Logger = lgr;
    }

    public int GetWheelCount()
    {
        return 4;
        this.Logger.LogSomething("GetWheelCount is returning 4");
    }       
}



IUnityContainer container = new UnityContainer();

container.RegisterType<ILog, MyLogger>();
container.RegisterType<IAnimal, Dog>();
container.RegisterType<IVehicle, Car>();


IAnimal animal = container.Resolve<IAnimal>();
animal.MakeNoise();
IVehicle veh = container.Resolve<IVehicle>();
int wheelCount = veh.GetWheelCount();

请注意,我只需要注册ILog一次。 Unity完成了使构造函数注入工作的魔力......当我调用container.Resolve时,我的两个对象都依赖于ILog。我正在解决INTERFACE,而不是具体的。

现在我试图用Java做同样的事情。

然而,当我使用Spring时,我发现了以下内容。

首先,Java .............与&#34;真实&#34;记录器。

 /* not my code........but portion shown here to show interface */
package org.apache.commons.logging;

public interface Log {
    public void info(Object message);
}







public interface IAnimal {

    void makeNoise();
}





import org.apache.commons.logging.Log;

public class Dog {

    private Log Logger;

    public Dog(Log lgr) {
        this.Logger = lgr;
    }

    public final void makeNoise() {
        this.Logger.info("Bark Bark Bark");
    }
}


public interface IVehicle {

    int getWheelCount();
}



import org.apache.commons.logging.Log;

public class Car {

    private Log Logger;

    public Car(Log lgr) {
        this.Logger = lgr;
    }

    public final int getWheelCount() {
        return 4;
        this.Logger.info("getWheelCount is returning 4");
    }
}

我的Spring的xml配置。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">


    <bean id="Jdk14LoggerBeanId"
      class="org.apache.commons.logging.impl.Jdk14Logger">
        <constructor-arg value="log" />
    </bean>


    <bean id="myVehicleId"
        class="com.mycompany.Car">
        <constructor-arg index="0" ref="Jdk14LoggerBeanId"/> 
    </bean>

    <bean id="myAnimalId"
        class="com.mycompany.Dog">
        <constructor-arg index="0" ref="Jdk14LoggerBeanId"/> 
    </bean>

</beans>

和用法。

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;



        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        BeanFactory factory = context;

        Car c = context.getBean(Car.class);
        int wc = c.getWheelCount();
        Dog d = context.getBean(Dog.class);
        c.makeNoise();

因此,有两件事情不符合我的个人喜好。

&#34;解决&#34;在java代码中.........是针对具体的狗和汽车,而不是IAnimal或IVehicle。 (是的,我知道在java中你不要用&#34; I&#34;作为前缀,但我试图保持重叠的一致性。)

在beans.xml中,我必须使用&#34; constructor-arg&#34;来声明Dog和Car的构造函数。

而在Unity / DotNot中,我只需要一次注册ILog类型。

我在互联网上找到了这个金块:

https://www.springbyexample.org/examples/core-concepts-dependency-injection-to-the-rescue.html

  

无接口注入???

     

表1.依赖关系注入类型DI类型描述构造函数   注入构造函数参数在实例期间注入   实例

     

Setter Injection这是最受青睐的依赖方法   注射在春天。依赖关系在对象中“设置”   在Spring配置文件中定义的setter方法。

     

接口注入目前在Spring中没有实现,但是由Avalon实现。这是一种不同类型的DI,涉及将项目映射到   注入特定的接口。

是否有针对Java的Ioc / DI注入更接近Unity / DotNet? (或者我想,有没有办法在Spring中做到这一点,我没有使用/看到??)

具体....我在哪里注册一切..我解决了界面,而不是具体的?

1 个答案:

答案 0 :(得分:1)

我会推荐hk2。它支持构造函数(或任何地方)中的接口注入,并且还具有stub generation等功能,可用于生成对测试/模拟有用的接口实现