Подтвердить что ты не робот

Зачем использовать CDI в Java EE

Я знаю, что есть много статей, которые объясняют, как использовать CDI в Java EE, но мне трудно понять, какую пользу это приносит. Например, предположим, что у меня есть класс, который в настоящее время использует экземпляр Foo. Я мог бы сделать

Foo myFoo = new Foo();

или

// Better, FooFactory might return a mock object for testing    
Foo myFoo = FooFactory.getFoo();

Я продолжаю читать, что с CDI я могу сделать:

@Inject
Foo myFoo;

но почему это лучше, чем предыдущий подход на основе factory? Я предполагаю, что есть другой вариант использования, о котором я не знаю, но я не смог его идентифицировать.

Если я понял ответы ниже, концепция заключается в том, что структура DI действует как главный объект factory, который настроен централизованно. Является ли это разумной интерпретацией?

Обновление

С тех пор я начал изучать Spring, и теперь это имеет гораздо больший смысл. Нижеприведенный абзац взят из Spring в Практике на примере класса AccountService, который, в свою очередь, использует экземпляр AccountDao. Я прошу прощения за длинную цитату, но я думаю, что это действительно зависит от того, почему вложенные ресурсы предлагают что-то по стандартной инициализации.

Вы могли бы создать AccountService с использованием нового ключевого слова, но создание объектов уровня сервиса редко бывает таким простым. Они часто зависят от DAO, почтовых отправителей, прокси-серверов SOAP и еще чего-то. Вы могли бы программно создать каждую из этих зависимостей в конструкторе AccountService (или через статическую инициализацию), но это приводит к жестким зависимостям и каскадным изменениям по мере их замены.

Кроме того, вы можете создавать зависимости извне и устанавливать их в AccountService с помощью методов setter или аргументов конструктора. Это приведет к устранению жестких внутренних зависимостей (если они были объявлены в интерфейсе AccountService по интерфейсу), но вы все равно дублируете код инициализации. Вот как вы создаете DAO и подключаете его до вашего AccountService Spring способ:

<bean id="accountDao" class="com.springinpractice.ch01.dao.jdbc.JdbcAccountDao"/>

<bean id="accountService"
    class="com.springinpractice.ch01.service.AccountService">
    <property name="accountDao" ref="accountDao"/>
</bean>

Сконфигурировав beans, как указано выше, ваша программа теперь может запросить экземпляр AccountService из ApplicationContext Spring, а среда Spring DI будет следить за тем, чтобы создать экземпляр всего, что требуется для создания экземпляра.

4b9b3361

Ответ 1

Люди, которые писали CDI, дали вам один большой объект factory; они сделали для вас работу, лучше, чем вы. Это XML-конфигурация или аннотация, поэтому вам не нужно вставлять все в код.

Двигатели впрыска зависимостей, такие как Spring, делают намного больше, чем ваш factory. Для дублирования всего, что они предлагают, потребуется несколько классов factory и одна строка кода.

Конечно, вам не нужно его использовать. Вы всегда можете изобрести свое собственное колесо. И вы должны - если ваша цель - научиться делать колеса или исключать зависимости.

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

оригинальная статья об инъекции зависимостей была написана Мартином Фаулером. Я бы рекомендовал его прочитать; это еще здорово, восемь лет спустя.

"до сих пор неясно, чем больше"

Вот несколько преимуществ:

  • Соединение с ослаблением
  • Более легкое тестирование
  • Улучшение слоев
  • Интерфейсный дизайн
  • Динамические прокси (segue to AOP).

Ответ 2

Цель использования инъекции зависимостей заключается в том, что код, использующий введенную вещь, не имеет зависимости от factory. С вашим примером кода factory существует встроенный в код код статического метода, который там не нужен с подходом DI.

То, что вводится myFoo, не должно знать о factory.

Ответ 3

На высоком уровне, как и в большинстве случаев на CompSci, он предлагает уровень косвенности (или абстракции), который в противном случае был бы жестко запрограммирован в вашем приложении как Foo myFoo = new Foo();. Это косвенное отношение приводит к слабо связанному коду, который делает вещи модульными, что упрощает замену, обслуживание, тестирование классов и подсистем другими классами проще.

Обратите внимание, что существует множество конструкций и шаблонов для косвенной/абстракции - инъекция зависимостей - это всего лишь один.

Другой аспект вашего вопроса: "Почему CDI?" - Хорошо, потому что кто-то уже сделал для вас работу. Вы всегда можете создавать свои собственные вещи, но обычно это пустая трата времени, когда целью является создание системы реального мира, которая должна выполняться в рамках бюджета и вовремя. Зачем беспокоиться о продуктах и ​​готовить, когда есть шеф-повар Michelin, который готов сделать для вас эту работу?

Ответ 4

Это важный и тонкий вопрос о том, что такое корпоративное программирование.

Название хорошо выбрано: контексты и зависимости.

CDI не имеет ничего общего с лучшим или более чистым кодом, это означает, что крупные организации могут создавать сложные, распределенные программные системы и обмениваться данными. Это означает, что 100% уверены, что правительства или другие бюрократии могут без разбора распределять автономные, хорошо документированные пакеты для каждого программного обеспечения, которым они управляют. Помните, что в эти дни можно вводить практически любые POJO.

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

  • Архитекторы предприятия этой крупной компании хотели бы, чтобы вы имеют такую ​​возможность, но, будучи младшим инженером-программистом, нет шанс получить ключи от БД.

  • Они также хотели бы защитить данные по сети, но компания не платит инженерам за реорганизацию аутентификации клиент каждый раз, когда им нужно поделиться записью данных.

  • Они хотели бы, чтобы вы могли иметь возможность запрашивать и обновлять эту информацию, но хотелось бы, чтобы транзакции обрабатывались на более высоком уровне чем любое приложение.

  • Они хотели бы, чтобы вы могли тестировать свои классы с помощью тривиальных макетов в блоках настройки.

  • Они хотели бы, чтобы связь между классами включала минимум статических методов.

  • И дальше и дальше...

В большинстве JSR, вероятно, есть "EAs хотели бы иметь возможность..." где-то там где-то.

CDI предпочтительнее, потому что он позволяет приложениям с большими (произвольными?) горизонтальными и вертикальными масштабами обмениваться контекстами, зависимостями и, следовательно, данными.

В словах Фаулера:

"Проблема в том, как я могу сделать эту ссылку, чтобы мой класс lister игнорируя класс реализации, но все же может разговаривать с чтобы выполнить свою работу".

"Но если мы хотим развернуть эту систему по-разному, нам нужно используйте плагины для взаимодействия с этими службами, чтобы мы могли используйте разные реализации в разных развертываниях."

"Подход, используемый этими контейнерами, заключается в обеспечении того, чтобы любой пользователь плагин следует за некоторыми соглашениями, которые позволяют отдельный ассемблер модуль для внедрения реализации в листер."

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

Еще две вещи:

  • Обратите внимание, что CDI существует мирно рядом с "шаблоном локатора сервисов", известным как JNDI в Java EE, что предпочтительнее, если разработчику клиента нужно будет выбрать один из множества одинаково типизированных альтернатив.

  • CDI - это больше огневой мощи, чем это необходимо во многих случаях, особенно в случае не предпринимательства (в буквальном смысле).