Исходя из 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, который я не использую / не вижу?)
Конкретно .... где я регистрирую все один раз .. и я разрешаю интерфейс,не бетон?