Spring @Autowired

218

Каковы плюсы и минусы использования @Autowired в классе, который будет подключен к Spring?

Просто чтобы прояснить, я говорю конкретно о аннотации @Autowired , а не об автопроводке в XML.

Я, вероятно, просто не понимаю этого, но для меня это выглядит почти как анти-паттерн - ваши классы начинают осознавать, что они связаны с DI-структурой, а не просто являются POJO. Может быть, я жажду наказания, но мне нравится иметь внешний XML-конфиг для bean-компонентов, и мне нравится иметь явные связи, так что я точно знаю, где и где проводка.

Энди Уайт
источник
4
Мне тоже интересна эта тема - настройка вашего приложения MVC с помощью аннотаций вместо XML, похоже, приведет к большому поиску «какой класс сопоставлен с этим URL?» «кто с этим справляется?». Мне нравится иметь один источник конфигурации
Matt B
6
термин «@Autowiring» здесь вводит в заблуждение. Поскольку вы также можете выполнить автоматическую разводку с конфигурацией XML, исходный вопрос следует перефразировать как «Плюсы и минусы использования аннотаций Spring». Предоставленный ответ фокусируется больше на аспектах автопроводки и меньше на аспектах использования аннотаций.
Neeme Praks
Возможный дубликат использования Understanding Spring @Autowired
tkruse

Ответы:

253

В течение долгого времени я считал, что имеет смысл иметь «централизованную, декларативную конфигурацию», такую ​​как XML-файлы, которые мы все использовали. Затем я понял, что большинство файлов в файлах не было конфигурацией - это никогда не менялось нигде после разработки, никогда. Затем я понял, что «централизованный» имеет значение только в довольно небольших системах - только в небольших системах вы когда-нибудь сможете получить файл конфигурации в целом . И какова на самом деле ценность понимания разводки в целом, когда одни и те же «разводки» в основном дублируются зависимостями в коде? Поэтому единственное, что я сохранил, - это метаданные (аннотации), которые все еще являются декларативными. Они никогда не меняются во время выполнения и никогда «конфигурационные» данные, которые кто-то изменит на лету - так что я думаю, что хранить их в коде - это хорошо.

Я использую полную автоматическую проводку столько, сколько я могу. Я люблю это. Я не вернусь к старому стилю, если не буду угрожать оружием. Мои причины для полного предпочтения @Autowiredсо временем изменились.

Прямо сейчас я думаю, что наиболее важной причиной использования автопроводки является то, что в вашей системе есть одна абстракция, которую нужно отслеживать. «Имя боба» фактически исчезло. Оказывается, имя компонента существует только из-за xml. Таким образом, полный слой абстрактных косвенных указаний (где вы бы связали имя bean-компонента "foo" с "bar" bean-компонента) пропал. Теперь я подключаю интерфейс «Foo» непосредственно к своему компоненту, и реализация выбирается профилем времени выполнения. Это позволяет мне работать с кодом при отслеживании зависимостей и реализаций. Когда я вижу в своем коде автосвязанную зависимость, я могу просто нажать кнопку «перейти к реализации» в моей среде IDE, и появится список известных реализаций. В большинстве случаев есть только одна реализация, и я прямо в классе. Жестяная банка' какая реализация используется (я утверждаю, что обратное ближе к истине с проводкой xml - забавно, как меняется ваша перспектива!)

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

Большинство систем, с которыми я когда-либо работал, имеют только одну конфигурацию рабочей среды выполнения. Там могут быть другие конфигурации для тестирования и так далее.

Я бы сказал, что полная автоматическая разводка - это рубин весны на рельсах: он охватывает понятие, что существует нормальная и распространенная схема использования, которой придерживаются большинство вариантов использования. С конфигурацией XML вы разрешаете много последовательного / противоречивого использования конфигурации, которое может / не может быть предназначено. Я видел, как много xml-конфигураций выходят за рамки несоответствий. Реорганизуется ли это вместе с кодом? Мысль нет. Есть ли эти вариации по какой-то причине? Обычно нет.

Мы почти не используем квалификаторы в нашей конфигурации и нашли другие способы решения этих ситуаций. Это явный «недостаток», с которым мы сталкиваемся: мы немного изменили способ кодирования, чтобы он стал более плавным при взаимодействии с автопроводкой: хранилище клиентов больше не реализует универсальный Repository<Customer>интерфейс, но мы создаем CustomerRepositoryрасширяемый интерфейс Repository<Customer>. Иногда есть подвох или два, когда дело доходит до подклассов. Но это, как правило, просто указывает нам направление более сильного набора текста, что, как я считаю, почти всегда является лучшим решением.

Но да, вы привязаны к определенному стилю DI, который в основном делает весна. Мы даже больше не публикуем сеттеры для зависимостей (так что вы можете утверждать, что мы +1 в отделе инкапсуляции / сокрытия информации) У нас все еще есть некоторый xml в нашей системе, но в основном xml содержит только аномалии. Полная автопроводка прекрасно интегрируется с XML.

Единственное , что нам теперь нужно для @Component, @Autowiredа остальные должны быть включены в JSR (как JSR-250 ), так что мы не должны связать с весной. Так происходило в прошлом ( java.util.concurrentвещи приходят на ум), поэтому я не был бы полностью удивлен, если это повторилось.

krosenvold
источник
5
Spring поддерживает javax.annotation / javax.inject, поэтому вам не нужно зависеть от кода от Spring.
Майкл Уайлс
26

Для меня вот то, что мне нравится / не нравится в весне и автоматическом подключении.

Плюсы:

  • Авто-проводка избавляет от неприятной конфигурации XML.
  • Гораздо проще использовать аннотации, которые позволяют вводить напрямую, используя поля, методы установки или конструкторы. Также позволяет аннотировать и «квалифицировать» введенные бобы.

Минусы:

  • Использование автоматического подключения и аннотаций делает вас зависимым от библиотек Spring, где, как и при настройке XML, вы можете выбрать запуск с Spring или без него. Как вы сказали, вы становитесь привязанными к структуре DI.
  • В то же время мне нравится возможность «квалифицировать» бины, для меня это делает код действительно грязным. Если вам нужно внедрить один и тот же компонент в нескольких местах, я видел повторение одного и того же имени строки. Мне кажется, это может привести к ошибкам.

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

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

Джаред Книпп
источник
3
Конфигурация xml становится намного менее неприятной, если вы используете бесплатный набор инструментов Springsource, который включает автозаполнение, графы бинов и т. д.
Шон Патрик Флойд,
Я полностью согласен с вами в том, что автоматическая разводка становится грязной и зависит от пружинных библиотек! Я никогда не использовал XML-конфигурацию и думаю, что мне пора идти по этому пути?
Джеймс 11
15

Мы переходим от @Autowire обратно к конфигурации XML в нашем большом проекте. Проблема заключается в очень низкой производительности начальной загрузки. Сканер автопроводки загружает все классы из пути поиска по автопроводке, поэтому многие классы загружаются с нетерпением во время инициализации Spring.

Masterhard
источник
1
Я обнаружил, что javaconfig может быть даже лучшим решением для запуска частичного контекста, что является большой победой. Но вы можете легко комбинировать их, используя @ Autowired / @ Inject для конструкторов (другими словами, переключитесь на инжекцию в конструктор).
Кросенволд
6

Там было очень мало дискуссий о переключении сред. Большинство проектов, над которыми я работал, было реальной проблемой для внедрения зависимостей в зависимости от среды, над которой мы работаем. С xml config это довольно просто с Spring EL, и я не знаю ни одного хорошего решения с аннотациями. Я только что понял один:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

Это должно работать, но не хорошее решение imho.

BTakacs
источник
Я открыл отдельную ветку об этом, и есть решение с помощью Spring @Profilesи @Configuration: blog.springsource.org/2011/02/14/… См. Также другую
ветку
4

Я перешел на @Autowire. Поддержка конфигурации XML для чего-либо, кроме небольшого проекта, стала самостоятельной задачей, и понимание быстро ухудшилось.

IntelliJ обеспечивает хорошую (не идеальную) поддержку Spring аннотаций.

Пол Маккензи
источник
3

Мой взгляд на эту тему заключается в том, что конфигурация xml снижает ясность кода, особенно в больших системах.

Аннотации типа @Component делают вещи еще хуже. Это заставляет разработчиков делать объекты изменяемыми, поскольку зависимости больше не могут быть окончательными, учитывая необходимость предоставления конструкторов по умолчанию. Зависимости должны быть либо введены через общедоступный сеттер, либо неуправляемы через @Autowired. [еще худшее внедрение зависимостей скомпрометировано с классами, которые создают свои зависимости, я все еще вижу это во вновь написанном коде!]. Под неконтролируемым я подразумеваю, что в больших системах, когда доступно несколько реализаций (или дочерних элементов) этого типа, становится гораздо сложнее понять, какая из реализаций была @Autowired, сложность, которая значительно усложняет исследование ошибок. Это также означает, что, предположительно, у вас есть профиль для тестовой среды и другой для производства,

Я придерживаюсь середины, где я объявляю свой класс (ы) конфигурации (конфигурация Spring на основе Java с использованием @Configuration)

Я объявляю все мои компоненты явно в классе (ах) конфигурации. Я использую только @Autowired в классе (ах) конфигурации, целью является ограничение зависимости от Spring для класса (ов) конфигурации

@Configuration находится в определенном пакете, это единственное место, где выполняется весеннее сканирование. (Это значительно ускоряет время запуска в крупных проектах)

Я стараюсь сделать все мои классы неизменяемыми, особенно объекты данных, JPA, Hibernate и Spring, а также многие библиотеки сериализации, кажется, подрывают это. Я избегаю всего, что вынуждает меня предоставлять сеттеры, или удаляю ключевое слово final из моего объявления свойства.

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

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

Charbel
источник
1

Вот некоторые из плюсов опыта

  • Упрощает настройку, потому что мы можем просто использовать аннотацию @Autowire
  • Не хочу использовать методы установки, поэтому класс будет более чистым

Cons

  • Плотная связь с XML-файлом, хотя мы используем DI
  • Трудно найти реализацию (но если вы используете хорошие идентификаторы, такие как intellij, вы можете избавиться от этого)

Что касается моего личного опыта, я не так часто использовал аннотацию @AutoWire, но в тестовых примерах.

Раджит Деланта
источник
1

Я действительно люблю писать с аннотациями, а не с XML. Согласно руководству Spring и последним версиям, XML и Annotation достигли одного и того же результата.

Это мой список

Pro:

  • Удалить бесполезную строку из XML
  • Упростите отладку кода: когда вы открываете класс, вы можете прочитать, что у вас есть в классе
  • Более быстрый процесс разработки, проект с 400 или более строками XML читабелен?

Минусы:

  • Не является стандартной реализацией Java, но вы можете переключиться на использование @Inject, который является стандартным Java API, поэтому компонент остается Pojo
  • Вы не можете просто использовать везде, подключение к БД и так далее, но это всего лишь мнение, я предпочитаю иметь место, где можно прочитать все конфигурации.
Лука Презиати
источник
0

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

Шубхам Капур
источник