Весна @ Автоматичне використання


218

Які плюси та мінуси використання @Autowired у класі, який буде підключений весною?

Просто для уточнення, я конкретно говорю про анотацію @Autowired , а не про автоматичне з'єднання в XML.

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


4
Мене також цікавить ця тема - конфігурація додатка MVC за допомогою анотацій замість XML здається, що це призведе до багатьох пошуків "який клас відображений у цій URL-адресі?" "хто з цим обробляє?". Мені подобається мати єдине джерело конфігурації
matt

6
термін "@Autowiring" тут, здається, вводить в оману. Оскільки ви також можете робити автоматичне з'єднання з конфігурацією XML, оригінальне запитання слід перефразовувати як "Плюси і мінуси використання весняних анотацій". Надана відповідь більше зосереджується на аспектах автопроводу та менше на аспектах використання анотацій.
Neeme Praks

Відповіді:


253

Тривалий час я вважав, що є значення в наявності "централізованої, декларативної, конфігурації", як файли xml, які ми всі використовували. Тоді я зрозумів, що більшість речей у файлах не має конфігурації - вона ніколи не змінювалася ніде після розробки, ніколи. Тоді я зрозумів, що "централізоване" має значення лише в досить малих системах - лише в невеликих системах ви зможете виправити файл конфігурації в цілому . І яка насправді цінність розуміння проводки в цілому, коли ті самі «проводки» здебільшого дублюються залежностями в коді? Тож єдине, що я зберігав - це метадані (анотації), які все ще є декларативними. Вони ніколи не змінюються під час виконання, і вони ніколи "конфігураційні" дані, які хтось змінить на ходу - тому я думаю, що зберігати їх у коді приємно.

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

Зараз я думаю, що найважливішою причиною використання автоматичної проводки є те, що у вашій системі є одна менша абстракція, яку слід відстежувати. "Ім'я квасолі" фактично не зникло. Виявляється, назва квасолі існує лише через xml. Таким чином, повний шар абстрактних непрямих (де ви переведете назву квасолі "foo" в бобову "бар") немає. Тепер я з'єдную інтерфейс "Foo" безпосередньо в моєму квасолі, і реалізація вибирається профілем часу виконання. Це дозволяє мені працювати з кодом при відстеженні залежностей та реалізації. Коли я бачу в моєму коді автоматичну провідну залежність, я можу просто натиснути клавішу "перейти до реалізації" в моєму IDE і з'являється список відомих реалізацій. У більшості випадків є лише одна реалізація, і я прямо в клас. Можна " яка реалізація використовується (я стверджую, що навпаки ближче до істини за допомогою xml-проводки - смішно, як змінюється ваша перспектива!)

Тепер ви можете сказати, що це просто дуже простий шар, але кожен шар абстракції, який ми додаємо до наших систем, збільшує складність. Я дійсно не думаю, що xml ніколи не додавав реальної цінності будь-якій системі, з якою я працював.

Більшість систем, з якими я коли-небудь працював, мають одну конфігурацію виробничого середовища. Можуть бути й інші конфігурації для тестування тощо.

Я б сказав, що повна автоматична проводка - це рубін рейки весни: вона охоплює уявлення про те, що існує нормальна і загальна схема використання, за якою слідує більшість випадків використання. З конфігурацією XML ви дозволяєте безліч послідовних / непослідовних використання конфігурації, які можуть / не можуть бути призначені. Я бачив, що стільки конфігурацій XML переповнюють непослідовність - чи вона переробляється разом з кодом? Не думав. Чи є ці варіанти з причини? Зазвичай ні.

Ми майже не використовуємо класифікаторів у нашій конфігурації та знаходили інші способи вирішення цих ситуацій. Це очевидний "недолік", з яким ми стикаємося: ми дещо змінили спосіб кодування, щоб зробити його більш взаємодіючим з автоматичним підключенням: репозиторій клієнтів більше не реалізує загальний Repository<Customer>інтерфейс, але ми робимо інтерфейс, CustomerRepositoryякий розширюється Repository<Customer>. Іноді також є хитрість чи два, коли мова йде про підкласи. Але зазвичай це просто спрямовує нас у напрямку сильнішого набору тексту, що, як я вважаю, майже завжди є кращим рішенням.

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

Єдине, що нам зараз потрібно - це включити решту @Component, @Autowiredа решту включити до JSR (як, наприклад, JSR-250 ), тому нам не доведеться пов'язувати весну. Це те, що відбувалося в минулому ( java.util.concurrentречі припадають на розум), тому я не був би зовсім здивований, якби це повторилося.


5
Javax.annotation / javax.inject підтримується весною, тому вам не потрібно мати кодову залежність від Spring.
Майкл Вілз

26

Для мене ось що мені подобається / не подобається у веснах та автоматичному проводці.

Плюси:

  • Автоматичне з'єднання позбавляється від неприємної конфігурації XML.
  • Набагато простіше використовувати анотації, які дозволяють вводити їх безпосередньо за допомогою полів, методів встановлення чи конструкторів. Також дозволяє коментувати та «кваліфікувати» введені боби.

Мінуси:

  • Використання автоматичного підключення та приміток робить вас залежним від бібліотек Spring, де, як і у конфігурації XML, ви могли вибрати для роботи з Spring або без нього. Як ви вже говорили, ви прив'язуєтесь до рамки DI.
  • У той же час мені подобається, що я можу "кваліфікувати" боби, що для мене це робить код справді безладним. Якщо вам потрібно ввести один і той же квасоля в декількох місцях, я бачив те саме ім’я рядка, яке повторювалося в усьому світі. Мені здається, це має потенціал помилок.

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

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


3
Конфігурація xml стає набагато менш неприємною, якщо ви користуєтесь безкоштовним пакетом інструментів Springsource Tool, який містить автодоповнення, графіки бобів тощо
Шон Патрік Флойд

Я повністю згоден з вами щодо того, що автоматична проводка стає безладним і залежним від весняних бібліотек! Я ніколи не використовував конфігурацію XML і думаю, що, можливо, я повинен пройти по цьому шляху?
James111

15

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


1
Я виявив, що javaconfig може бути навіть кращим рішенням для запуску часткових контекстів, що є великою виграшею, але ви можете їх легко поєднувати, використовуючи @ Autowired / @ Inject на конструкторах (іншими словами, перейти на інжектор конструктора).
krosenvold

6

Про комутаційні середовища було дуже мало дискусій. Більшість проектів, над якими я працював, було справжньою проблемою - вводити залежності залежно від середовища, над яким ми працюємо. З конфігурацією xml це досить просто з Spring EL, і я не знаю жодного приємного рішення з анотаціями. Я тільки що з’ясував:

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

Це має бути робочим, але не приємним рішенням.


Я відкрив окрему тему про це, і є рішення з Spring @Profilesі @Configuration: blog.springsource.org/2011/02/14/… Дивіться також іншу тему: stackoverflow.com/questions/13490393 / ...
BTakacs

4

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

IntelliJ забезпечує хорошу (не ідеальну) підтримку весняних анотацій.


3

Думаю, що конфігурація xml знижує чіткість коду, особливо у великих системах.

Анотації, як-от @Component, ще гірша. Це спонукає розробників робити об’єкти змінними, оскільки залежності вже не можуть бути остаточними, враховуючи, що конструктори за замовчуванням повинні бути надані. Залежності потрібно або вводити через громадський сетер, або неконтрольовано через @Autowired. [Ще гірша ін'єкція залежності залежає від класів, які інстанціюють їх залежності, я все ще бачу це в нещодавно написаному коді!]. Я маю на увазі, що у великих системах, коли доступно декілька реалізацій (або дітей) цього типу, він набагато більше бере участь у розумінні, яка з реалізацій була @Autowired, складність, яка робить дослідження помилок набагато складніше. Це також означає, що, мабуть, у вас є профіль для тестового середовища та інший для виробництва,

Я дотримуюсь середнього місця, де я оголошую свої класи (-и) конфігурації ((Ява на основі Spring конфігурації за допомогою @Configuration)

Я декларую всі мої квасолі прямо в класі (-і) конфігурації. Я використовую @Autowired лише в класі конфігурації, мета - обмежити залежність від Spring на клас конфігурації

@Configuration знаходиться у певному пакеті, це єдине місце, де працює весняне сканування. (Це значно прискорює час запуску у великих проектах)

Я прагну зробити так, щоб усі мої класи були непорушними, особливо об'єкт даних, JPA, Hibernate та Spring, а також багато бібліотек серіалізації, здається, це підривають. Я ухиляюся від усього, що змушує мене надати налаштування, або видалити остаточне ключове слово з моєї декларації про властивості.

Зменшуючи можливості зміни об'єктів після їх створення, істотно зменшує помилки у великій системі, а також скорочує час на пошук помилки, коли така існує.

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


1

Ось деякі з досвіду
плюсів

  • Полегшує налаштування, оскільки ми можемо просто використовувати анотацію @Autowire
  • Не хочеться використовувати методи сеттера, тому клас буде більш чистим

Мінуси

  • Щільно пасуйте до XML-файлу, хоча ми використовуємо DI
  • Важко знайти реалізацію (Але якщо ти використовуєш такі добрі ідеї, як Intellij, впевнений, що ти можеш позбутися цього)

Як на моєму особистому досвіді, я не дуже використовував анотацію @AutoWire, але в тестових випадках.


1

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

Це мій список

Про:

  • Видаліть марну лінію з xml
  • Спростіть налагодження коду: відкриваючи клас, ви можете прочитати, що у вас є в класі
  • Що швидше розвивається, проект з 400 і більше рядками XML читається?

Мінуси:

  • Це не стандартна реалізація Java, але ви можете перейти на використання @Inject, що є стандартним Java Api, тому боб залишається Pojo
  • Ви не можете просто використовувати скрізь, db-з'єднання тощо, але це лише думка, я вважаю за краще місце, де читаються всі конфігурації.

0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.