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