Сеттер Д.И. против конструктора Д.И. весной? - PullRequest
24 голосов
/ 15 октября 2011

Spring имеет два типа DI: установочный DI и строительный DI.

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

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

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

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

Ответы [ 7 ]

24 голосов
/ 15 октября 2011

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

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

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

16 голосов
/ 15 октября 2011

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

9 голосов
/ 26 февраля 2014

Внедрение в конструктор: Мы вводим зависимости через конструктор.

Как правило, мы можем использовать для Обязательные зависимости.

Если вы используете инжектор Конструктор, есть один недостаток, который называется "Круговая зависимость".

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

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

Внедрение сеттера: Мы вводим зависимости через методы сеттера.

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

Можно повторно вводить зависимости с помощью Инъекция сеттера. Это невозможно в Инъекция в конструктор.

2 голосов
/ 03 августа 2018

Согласно содержимому из spring.io начиная с Spring 5 и далее

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

Команда Spring обычно рекомендует внедрение конструктора, поскольку оно позволяет реализовывать компоненты приложения как неизменяемые объекты и обеспечиватьчто требуемые зависимости не равны нулю.Более того, внедренные конструктором компоненты всегда возвращаются клиентскому (вызывающему) коду в полностью инициализированном состоянии.В качестве примечания следует отметить, что большое количество аргументов конструктора является неприятным запахом кода, подразумевая, что класс, вероятно, имеет слишком много обязанностей и должен быть подвергнут рефакторингу, чтобы лучше решать правильное разделение проблем.используется для необязательных зависимостей, которым могут быть назначены разумные значения по умолчанию в классе.В противном случае проверки не-null должны выполняться везде, где код использует зависимость.Одним из преимуществ внедрения сеттера является то, что методы сеттера делают объекты этого класса пригодными для реконфигурации или повторного внедрения позже.Поэтому управление через JMX MBeans является убедительным примером использования для инъекции сеттера.

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

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

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

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

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

1 голос
/ 15 октября 2011

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

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

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

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

0 голосов
/ 20 ноября 2014

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


Обратите внимание , что использование аннотации @Required в установщике может использоваться для созданиясеттеры требуют зависимости.

0 голосов
/ 15 сентября 2014

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...