Преамбула
Переведено сfield-injection-is-not-recommended, добавляя свое собственное народное понимание!
вводить
Когда я сегодня использовал Idea для написания кода, я увидел предупреждающее сообщение, отображаемое в предыдущем проекте. Я просмотрел его. Это следующий код?
@Autowire
private JdbcTemplate jdbcTemplate;
Быстрое предупреждающее сообщение
Field injection is not recommended Inspection info: Spring Team recommends: "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".
这段是Spring工作组的建议,大致翻译一下:
属性字段注入的方式不推荐,检查到的问题是:Spring团队建议:"始终在bean中使用基于构造函数的依赖项注入,
始终对强制性依赖项使用断言"
Как показано
Инъекционный метод
Хотя текущая документация по Spring Framework (5.0.3) определяет только два основных типа внедрения, на самом деле их три:
- Внедрение зависимостей на основе конструктора
public class UserServiceImpl implents UserService{ private UserDao userDao; @Autowire public UserServiceImpl(UserDao userDao){ this.userDao = userDao; } } - Внедрение зависимостей на основе сеттера
public class UserServiceImpl implents UserService{ private UserDao userDao; @Autowire public serUserDao(UserDao userDao){ this.userDao = userDao; } } - Внедрение зависимостей на основе полей
public class UserServiceImpl implents UserService{ @Autowire private UserDao userDao; }
Внедрение зависимостей на основе поля получает желтую карточку в Idea, но оно также наиболее широко используется из-за своей простоты и удобства.Вы даже можете увидеть этот метод внедрения в некоторых руководствах по Spring, хотя в документации он не задокументирован. это (похоже на нарушение закона)
Как показано
Недостатки внедрения зависимостей на основе полей
-
за тоfinalМодифицированные переменные работают плохо
IOC Spring использует форму набора для внедрения атрибутов, но переменные конечного типа должны быть инициализированы в процессе вызова конструктора класса.Внедрение зависимостей на основе поляГде это нельзя сделать. использовать толькоВнедрение зависимостей на основе конструктораПуть
-
покрытиеДизайн-мышление с единой ответственностью
Все мы знаем, что в дизайне ООП естьмышление единой ответственности, если вы используетеВнедрение зависимостей на основе конструктораКогда вы используете IOC Spring таким образом, когда вы вводите слишком много, параметры этого конструктора будут огромными, как показано ниже Когда вы видите так много параметров в конструкторе этого класса, вы, естественно, будете думать о:Нарушает ли этот класс идею единой ответственности?.но использоватьВнедрение зависимостей на основе поляне даст вам заметить, вы погрузитесь в @Autowire
public class VerifyServiceImpl implents VerifyService{ private AccountService accountService; private UserService userService; private IDService idService; private RoleService roleService; private PermissionService permissionService; private EnterpriseService enterpriseService; private EmployeeService employService; private TaskService taskService; private RedisService redisService; private MQService mqService; public SystemLogDto(AccountService accountService, UserService userService, IDService idService, RoleService roleService, PermissionService permissionService, EnterpriseService enterpriseService, EmployeeService employService, TaskService taskService, RedisService redisService, MQService mqService) { this.accountService = accountService; this.userService = userService; this.idService = idService; this.roleService = roleService; this.permissionService = permissionService; this.enterpriseService = enterpriseService; this.employService = employService; this.taskService = taskService; this.redisService = redisService; this.mqService = mqService; } } -
Тесно связанный с механизмом IOC Spring
когда вы используетеВнедрение зависимостей на основе поляПри использовании этого метода вы действительно можете опустить методы типов шаблонов, таких как конструкторы и сеттеры.Однако вы передали весь контроль IOC Spring, а другие классы хотят сбросить одно из введенных вами свойств, которое не может быть обработано (из Конечно, Reflection может это сделать.) Целью самого Spring является развязка и инверсия зависимостей, и в результате, снова связываясь с инжектором класса (Spring в этом случае), теряется развязка класса, достигнутая путем автоматического связывания полей класса. . , что делает класс недопустимым за пределами контейнера Spring.
-
скрыть зависимости
Когда вы используете IOC Spring, внедренный класс должен использовать некоторые методы открытого типа (конструктор и метод типа установки) для выражения во внешний мир: какие зависимости мне нужны.Внедрение зависимостей на основе поляМетод в основном имеет форму private, а private запечатывает атрибуты в классе.
-
Невозможно очистить внедренные свойства
Внедрение зависимостей на основе поляметод, вы не можете получить этот класс при запуске программы, он будет получен только при использовании реального бизнеса. В общем, эта инъекция ненулевая. немного поздно.Если он выставлен при запуске, ошибка может быть исправлена быстро (конечно, вы можете добавить проверку аннотаций).Если вы хотите внедрить свойства, вы хотите использовать это Введенный объект манипулирует чем-то, вы не можете сделай это. Примеры, с которыми я сталкивался: какая-то информация о конфигурации, некоторые люди всегда ошибаются, и они не знают об ошибках, пока не протестируют бизнес-этап, например, изначальное количество потоков случайно настроено на 3000, и машина действительно кричит. Ах, в это время необходимо сделать механизм обнаружения, когда какое-то значение введено.
В заключение
Из вышеизложенного мы видим, что,Внедрение зависимостей на основе поляметод имеет много недостатков, мы должныИзбегайте внедрения зависимостей на основе полей, Рекомендуемый способ - использоватьКонструктор на основеа такжевнедрение зависимостей на основе сеттера.Для необходимых зависимостей рекомендуется использоватьКонструктор на основеинъекции, чтобы сделать их неизменяемыми и не допустить, чтобы они были нулевыми. Для необязательных зависимостей рекомендуется использоватьИнъекция на основе сеттера
постскриптум
Переведено сfield-injection-is-not-recommended, добавляя свое собственное народное понимание!