Setter DI или Constructor DI весной?

Весна имеет два типа DI: setter DI и конструкцию DI.

DI на основе конструктора фиксирует порядок, в котором необходимо вводить зависимости. Setter based DI не предлагает этого.

Сеттер на основе DI помогает нам вводить зависимость только тогда, когда это требуется, а не требовать ее во время строительства.

Я не вижу каких-либо других существенных различий, так как оба типа Spring DI предоставляют одни и те же функции – как установщик, так и конструктор DI вводят зависимость при запуске кода. Конечно, конструктор DI будет делать это через конструктор, в то время как setter DI будет делать это через сеттер сразу после построения объекта, но это не имеет никакого значения для разработчика с точки зрения производительности и т. Д. Оба они также предлагают средства для указания порядка инъекции зависимостей.

Я ищу сценарий, в котором один дает отличное преимущество перед другим или где один тип полностью непригоден.

Когда дело доходит до весны, конкретные плюсы и минусы:

  • Инъекция конструктора (из определения) не позволяет создавать круговые зависимости между фасолью. Это ограничение на самом деле является преимуществом впрыска конструктора. Spring может разрешать циклические зависимости, когда используется инъекция setter, даже если вы даже не заметили.

  • С другой стороны, если вы используете инъекцию конструктора, CGLIB не может создать прокси-сервер, заставляя вас использовать прокси-серверы на основе интерфейса или конструктор no-arg. См .: SPR-3150

Вы должны принимать решения, основываясь на соображениях дизайна, а не на инструментах (Spring). К сожалению, Spring научила нас использовать инъекцию setter, потому что, когда она была изначально задумана, в Java не было такой вещи, как «аннотация», а в XML, установка инъекций и выглядит намного лучше. Сегодня мы освобождаемся от этих ограничений, что позволяет ему снова стать дизайнерским решением. Ваши бобы должны использовать инъекцию конструктора для любых зависимостей, которые требуются при вставке bean и setter для зависимостей, которые являются необязательными и имеют разумный дефолт, более или менее, поскольку OOD рассказывал нам с самого начала.

Инъекция конструктора: мы вводим зависимости через конструктор.

Обычно мы можем использовать для обязательных зависимостей.

Если вы используете инъекцию конструктора, есть один недостаток, называемый «Circular Dependency».

Круговая зависимость: Предположим, что A и B. A зависит от B. B зависит от A. В этом конструкторе инъекция будет неудачной. В это время инъекция Setter полезна.

Если состояние объекта не является непоследовательным, он не будет создавать объект.

Setter Injection: мы вводим зависимости через методы Setter.

Это полезно для не обязательных зависимостей.

Можно повторно вводить зависимости, используя Setter Injection. Это невозможно в инжекции конструктора.

Предпочитают инъекцию сеттера.

Подумайте, что будет без весны (как заметил Райан). Не могли бы вы передать зависимости в конструкторе? Если слишком много зависимостей, это кажется неправильным. С другой стороны, конструктор может использоваться для обеспечения правильного состояния объекта – требует всех зависимостей и проверки, не являются ли они ненужными.

Прокси – это еще одна вещь (как заметил Томаш) – вам понадобится конструктор-манекен, который победит всю идею.

Существует 3-й вариант btw – инъекция поля. Я, как правило, использую это, хотя это не такое хорошее дизайнерское решение, потому что оно экономит дополнительный сеттер, но если он используется вне весны, мне придется добавить установщика.

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

Поскольку вы можете смешивать оба,
Constructor DI – и Setter-based DI ,
это хорошее правило для использования аргументов конструктора для обязательных зависимостей и сеттеров для необязательных зависимостей .

Обратите внимание, что использование annotations @Required для сеттера может быть использовано для создания требуемых зависимостей сеттера.

Согласно содержанию от spring.io начиная с 5-й весны

Поскольку вы можете смешивать DI на основе конструктора и сеттера, хорошим правилом является использование конструкторов для обязательных зависимостей и методов настройки или методов настройки для необязательных зависимостей. Обратите внимание, что использование annotations @Required в методе setter можно использовать для того, чтобы сделать свойство требуемой зависимостью.

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

Вставка Setter должна использоваться только для дополнительных зависимостей, которым могут быть присвоены разумные значения по умолчанию в classе. В противном случае во всех случаях, когда код использует зависимость, должны выполняться не-нулевые проверки. Одно из преимуществ инъекции сеттера заключается в том, что методы setter делают объекты этого classа пригодными для реконфигурации или повторной инъекции позже. Таким образом, управление через JMX MBeans является убедительным прецедентом для инъекций setter.

Вот ссылка на приведенную выше цитату

Но все типы инъекций доступны, и ни один из них не устарел. На высоком уровне вы получаете одинаковые функциональные возможности для всех типов инъекций.

Короче говоря, выберите тип инъекции, который лучше всего подходит для вашей команды и проекта.

Рекомендации команды Spring и независимых сообщений в блогах будут меняться со временем. Нет жесткого правила.

Если особый стиль инъекции не был рекомендован командой Spring, они будут отмечать его как устаревшее или устаревшее. Это не относится ни к одному из стилей инъекций.

  • Как регистрировать HttpRequest и HttpResponse в файле?
  • получение исключения: не определен bean с именем «springSecurityFilterChain»
  • Можно ли настроить SpringMVC для обработки всех запросов, но исключить каталоги статического содержимого?
  • Самовсасывание с пружиной
  • Невозможно Autowire @Repository аннотированный интерфейс в Spring Boot
  • Отключить безопасность для модульных тестов с весенней загрузкой
  • Весенний язык выражений (SpEL) с @Value: доллар против hashа ($ против #)
  • Как использовать Spring перехватчики Hibernate в Spring Boot?
  • Весенние данные и исходный запрос с разбивкой на страницы
  • Spring Boot JPA - настройка автоматического повторного подключения
  • Как java-настроить отдельные источники данных для весенних пакетных данных и бизнес-данных? Должен ли я это сделать?
  • Давайте будем гением компьютера.