Ioc / DI в Java, который поддерживает разрешение интерфейса - PullRequest
0 голосов
/ 13 июня 2018

Исходя из 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 для любого из моих 2 объектов, которые зависели от ILog.И что я решаю ИНТЕРФЕЙС, а не конкретный.

Теперь я пытаюсь сделать то же самое в Java.

Однако, когда я использую Spring, я нахожу следующее.

Во-первых, Java ............. с "настоящим" Logger.

 /* 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");
    }
}

Моя конфигурация xml для Spring.

<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();

Итак, есть две вещи, которые не соответствуют моим личным предпочтениям.

«Решимость» в коде Java ........ для конкретного пса и автомобиля, а не животного или автомобиля.(да, я знаю, что в Java вы не используете префикс «I», но я стараюсь, чтобы перекрытие было согласованным).

в файле beans.xml, я должен объявить конструктор для обоихСобака и Автомобиль, используя "constructor-arg".

Принимая во внимание, что в Unity / DotNot мне нужно только один раз зарегистрировать тип ILog.

Я нашел этот слепок в интернете:

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

Нет внедрения интерфейса ???

Таблица 1. Типы внедрения зависимостей Тип DI Описание Инъекция конструктора Аргументы конструктора вводятся во время создания экземпляра.

Внедрение сеттера Это наиболее популярный метод внедрения зависимостей в Spring.Зависимости «устанавливаются» в объектах с помощью методов установки, определенных в файле конфигурации Spring.

Внедрение интерфейса Это не реализовано в Spring в настоящее время, но Avalon.Это другой тип DI, который включает в себя отображение элементов для внедрения в определенные интерфейсы.

Есть ли Ioc / DI-инъекция для Java, которая ближе к Unity / DotNet?(Или я думаю, есть ли способ сделать это в Spring, который я не использую / не вижу?)

Конкретно .... где я регистрирую все один раз .. и я разрешаю интерфейс,не бетон?

1 Ответ

0 голосов
/ 14 июня 2018

Я бы порекомендовал hk2 .Он поддерживает внедрение интерфейса в конструкторах (или в любом месте), а также имеет такие функции, как создание заглушки , которые можно использовать для генерации реализаций интерфейсов, которые полезны для тестирования / проверки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...