Разве автоматическое подключение не ограничивает цель IoC? - PullRequest
7 голосов
/ 17 декабря 2010

IoC хорош, но, используется с автопроводкой (@EJB, @Autowired, @Inject, @SpringBean ...), вы не думаете, что это ограничивает цель IoC?

На самом деле я не так много знаю об автомобильных системах в разных средах, но кажется, что они в основном основаны на типах.

Когда вы используете @EJB в IService, вам нужно иметь только одну реализацию ServiceImpl, чтобы она работала.

Что если нам нужно много реализаций?

Кажется, некоторые аннотации с автопроводкой могут иметь аргументы. Для примера в Stripes вы можете сделать: @SpringBean ( "xxxService") Где xxxService - это инициализированный весной компонент.

В таком случае, хорошо, вы не делаете "new XxxServiceImpl ()" Но вы по-прежнему помещаете жестко запрограммированную ссылку на реализацию сервиса, которую вы хотите использовать в своем бине. Это просто не ссылка на класс, а ссылка на bean-компонент Spring для реализации ...

Что вы думаете об этом? Мне нравится автопроводка, но я просто удивляюсь ....

Ответы [ 4 ]

6 голосов
/ 17 декабря 2010

Да, существуют ограничения на автоподключение (только одна реализация интерфейса с автопроводкой), поэтому он отказывается от части гибкости IoC, когда дело доходит до внедрения правильной реализации.

Тем не менее, я считаю, что автоматическое подключение - это просто способ уменьшить конфигурацию. Таким образом, когда 90% ваших зависимостей могут быть автоматически подключены, вы, как правило, в итоге получаете меньше конфигурации в целом (а оставшаяся конфигурация имеет большое значение, поскольку содержит только важные (зависящие от реализации) биты)

2 голосов
/ 17 декабря 2010

В ответ на комментарии приведен пример имен семантических бинов вместо «usedService» и «notUsedService».Обычная система хранит некоторые данные между серверами, но некоторые хранятся только в одном месте.

@Autowired
@Qualifier("customerDataSource")
DataSource ds;

@Autowired
@Qualifier("geoipDataSource")
DataSource geoip;

и в XML:

<bean id="customerDataSource" class="...ShardedDataSource">
  <property name="dataSources">
    <list>
      <value><ref local="ds1"/>
      <value><ref local="ds2"/>
    </list>
  </property>
</bean>

<bean id="ds1" class="...DataSource">
  ...
</bean>

<bean id="ds2" class="...DataSource">
  ...
</bean>

<alias name="ds2" alias="geoipDataSource"/>
2 голосов
/ 17 декабря 2010

Я сомневаюсь, что это можно считать объективным вопросом, но давайте попробуем.

У меня было довольно много дискуссий по этому поводу, и, конечно, не только вы так думаете.

Да, такое поведение делает IoC несколько бессмысленным. Это по-прежнему упрощает задачу, поскольку вам не нужно самим определять идеальный порядок подключения, но вы теряете преимущество возможности переключения реализаций путем изменения файла конфигурации, что является одной из причин, по которым мы начали с IoC.

Похоже, сейчас есть два основных подхода к переключению между реализациями:

  1. Использовать квалификаторы

Вы можете добавить аннотацию к вашей реализации, а другую - к точке внедрения, которая сообщит контейнеру, какую вы хотите использовать. Тем не менее, вы все равно должны изменить свой код в двух местах, так что это то же самое, что реализовать подчиненный интерфейс и связать его по типу. Это также все еще жестко закодировано.

  1. Использовать beanconfigurer

Spring имеет эту концепцию beanconfigurer, которая просто заменяет старые xml-файлы. Вы можете обрабатывать конфигурацию в определенном классе, который сообщит контейнеру, как подключиться. Я не вижу преимущества перед старым стилем (по этой причине синтаксис xml более читабелен), но я думаю, что это дело вкуса.

Для меня единственный способ использовать автоматическую разводку по типу приличным способом - играть с classpath, так что вы можете использовать mock вместо реализаций, добавив другой класс. Но так как java classpath имеет такой удобный интерфейс, я также не думаю, что это проще, чем старый способ xml.

Итак, в конце концов, я думаю, что все сводится к вкусу. Да, автопроводка с использованием аннотаций намного проще, но она, как вы и говорите, жестко запрограммирует вашу конфигурацию в вашем коде. Возникает вопрос: действительно ли это так часто меняется, что оправдывает подход «мягкого кодирования»?

0 голосов
/ 17 декабря 2010

Вы можете попробовать автоподключение по имени .Что решит вашу проблему.

Если у вас есть жесткие требования к автопроводке по типу.Затем вы можете указать, как это,

<bean id="PersonBean1" class="com.mkyong.common.Person">
        <property name="name" value="mkyong1" />
        <property name="address" value="address 1" />
        <property name="age" value="28" />
    </bean>

    <bean id="PersonBean2" class="com.mkyong.common.Person">
        <property name="name" value="mkyong2" />
        <property name="address" value="address 2" />
        <property name="age" value="28" />
    </bean>

, и вы можете указать bean-компонент в вашем классе, например,

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Customer 
{
    @Autowired
    @Qualifier("PersonBean1")
    private Person person;
    private int type;
    private String action;
    //getter and setter methods
}

Надеюсь, это решит вашу проблему.

...