Я могу говорить только из опыта работы с Guice, но вот мое мнение. Суть в том, что конфигурация на основе аннотаций значительно сокращает объем записи, которую необходимо записать, чтобы связать приложение вместе, и упрощает изменение того, что зависит от чего ... часто даже без необходимости касаться самих файлов конфигурации. Это достигается тем, что самые распространенные случаи становятся абсолютно тривиальными за счет усложнения обработки некоторых относительно редких случаев слегка .
Я думаю, что проблема в том, чтобы быть слишком догматичным в том, что у классов "нет представления об инъекциях". Не должно быть ссылки на контейнер для инъекций в коде класса. Я абсолютно согласен с этим. Однако мы должны четко уяснить один момент: аннотации не являются кодом . Сами по себе они ничего не меняют в том, как ведет себя класс ... вы все равно можете создать экземпляр класса с аннотациями, как если бы их вообще не было. Таким образом, вы можете полностью прекратить использование контейнера DI и оставить там аннотации, и никаких проблем не возникнет.
Когда вы решаете не предоставлять подсказки метаданных о внедрении в классе (то есть аннотации), вы выбрасываете ценный источник информации о том, какие зависимости требуются этому классу. Вы вынуждены либо повторять эту информацию в другом месте (скажем, в XML), либо полагаться на ненадежную магию, такую как автоматическое подключение, которая может привести к неожиданным проблемам.
Чтобы ответить на некоторые ваши конкретные вопросы:
Помогает избавиться от XML
Многие вещи плохи в конфигурации XML.
- Это ужасно многословно.
- Без специальных инструментов небезопасно.
- Это обязывает использовать строковые идентификаторы. Опять же, небезопасно без поддержки специального инструмента.
- Не использует никаких возможностей языка, требуя, чтобы все виды некрасивых конструкций делали то, что можно сделать с помощью простого метода в коде.
Тем не менее, я знаю, что многие люди используют XML достаточно долго, и они убеждены, что это просто замечательно, и я не собираюсь менять свое мнение.
Во многих случаях существует только одна реализация для каждого интерфейса
Часто существует только одна реализация каждого интерфейса для отдельной конфигурации приложения (например, производство). Дело в том, что при запуске приложения вам обычно нужно привязать интерфейс только к одной реализации. Затем он может быть использован во многих других компонентах. С конфигурацией XML вы должны указать каждому компоненту, который использует этот интерфейс, чтобы использовать эту конкретную привязку этого интерфейса (или «bean», если хотите). В конфигурации на основе аннотаций вы просто объявляете привязку один раз , а все остальное позаботится автоматически. Это очень важно и значительно уменьшает объем конфигурации, которую вы должны написать. Это также означает, что когда вы добавляете новую зависимость к компоненту, вам часто вообще не нужно ничего менять в вашей конфигурации!
То, что у вас есть фиктивные реализации какого-то интерфейса, не имеет значения. В модульных тестах вы обычно просто создаете макет и передаете его себе ... это не связано с конфигурацией. Если вы установите полную систему для интеграционных тестов с определенными интерфейсами, используя вместо этого макеты ... это ничего не изменит. Для запуска интеграционного теста системы вы по-прежнему используете только одну реализацию, и вам нужно настроить ее только один раз.
XML: вы можете внедрить что угодно куда угодно
Вы можете легко сделать это в Guice, и я думаю, что вы можете сделать это и в CDI.Таким образом, это не значит, что вам абсолютно запрещено делать это с помощью системы конфигурации на основе аннотаций.Тем не менее, я бы рискнул сказать, что большинство внедренных классов в большинстве приложений - это классы, которые можно добавить к себе @Inject
, если его еще нет.Наличие легкой стандартной библиотеки Java для аннотаций (JSR-330) еще больше упрощает для других библиотек и каркасов предоставление компонентов с аннотированным конструктором @Inject
в будущем.
Более одной реализацииинтерфейса
Квалификаторы являются одним из решений этого, и в большинстве случаев должно быть просто отлично.Однако в некоторых случаях вы хотите сделать что-то, когда использование квалификатора для параметра в определенном введенном классе не сработает ... часто потому, что вы хотите иметь несколько экземпляров этого класса, каждый из которых используетдругая реализация интерфейса или экземпляр.Guice решает эту проблему с помощью PrivateModule
s.Я не знаю, что CDI предлагает в этом отношении.Но, опять же, это тот случай, который находится в меньшинстве, и не стоит заставлять остальную часть вашей конфигурации страдать от этого, пока вы справитесь с этим.