Во-первых, и это самое главное - все бины Spring управляются - они «живут» внутри контейнера, называемого «контекстом приложения».
Во-вторых, каждое приложение имеет точку входа в этот контекст. Веб-приложения имеют сервлет, JSF использует el-resolver и т. Д. Кроме того, есть место, где контекст приложения загружается, а все компоненты - автоматически подключаются. В веб-приложениях это может быть слушатель запуска.
Автопроводка происходит путем помещения экземпляра одного компонента в нужное поле в экземпляре другого компонента. Оба класса должны быть bean-компонентами, то есть они должны быть определены для жизни в контексте приложения.
Что такое «жизнь» в контексте приложения? Это означает, что контекст создает объекты, а не вы. Т.е. - ты никогда не сделаешьnew UserServiceImpl()
- контейнер находит каждую точку впрыска и устанавливает там экземпляр.
В ваших контроллерах у вас просто есть следующее:
@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {
// Tells the application context to inject an instance of UserService here
@Autowired
private UserService userService;
@RequestMapping("/login")
public void login(@RequestParam("username") String username,
@RequestParam("password") String password) {
// The UserServiceImpl is already injected and you can use it
userService.login(username, password);
}
}
Несколько заметок:
- В ваших
applicationContext.xml
вы должны включить <context:component-scan>
так , чтобы классы сканируются для @Controller
, @Service
и т.д. аннотаций.
- Точкой входа для приложения Spring-MVC является DispatcherServlet, но он скрыт от вас, и, следовательно, прямое взаимодействие и загрузка контекста приложения происходит за сценой.
UserServiceImpl
также должен быть определен как bean - либо с <bean id=".." class="..">
использованием, либо с использованием @Service
аннотации. Поскольку он будет единственным разработчиком UserService
, он будет введен.
- Помимо
@Autowired
аннотации, Spring может использовать XML-конфигурируемую автоматическую разводку. В этом случае все поля, которые имеют имя или тип, совпадающий с существующим компонентом, автоматически вводятся в компонент. Фактически, это было первоначальной идеей автопроводки - вводить поля с зависимостями без какой-либо настройки. Другие аннотации, такие как @Inject
, @Resource
также могут быть использованы.
Зависит от того, хотите ли вы использовать маршрут аннотаций или маршрут определения XML-компонента.
Скажем, у вас есть бобы, определенные в вашем
applicationContext.xml
:Автопроводка происходит при запуске приложения. Таким образом, в
fooController
, который ради аргументов хочет использоватьUserServiceImpl
класс, вы должны аннотировать его следующим образом:Когда он видит
@Autowired
, Spring будет искать класс, который соответствует свойству вapplicationContext
, и вставляет его автоматически. Если у вас более одногоUserService
компонента, вам нужно будет определить, какой из них использовать.Если вы делаете следующее:
Это не поднимет,
@Autowired
если вы не установите это самостоятельно.источник
bean id
вapplicationContext.xml
. Нам нужно определитьuserService
переменную сUserService
типом. Так зачем делать запись вxml
файле.@Autowired
это аннотация, представленная в Spring 2.5, и она используется только для инъекций.Например:
источник
@Autowired
не означает, что «вы можете использовать все функции (методы) и переменные вB
классе из классаA
». То, что он делает, приводит экземплярA
в экземплярыB
, так что вы можете сделатьa.getId()
изB
.Как
@Autowired
работает внутренне?Пример:
XML-файл будет выглядеть одинаково, если не использовать
@Autowired
:Если вы используете
@Autowired
то:XML-файл будет выглядеть одинаково, если не использовать
@Autowired
:Если все еще есть какие-то сомнения, пройдите демонстрацию ниже
Как @Autowired работает внутри?
источник
Вам просто нужно аннотировать свой класс обслуживания
UserServiceImpl
с помощью аннотации:Контейнер Spring позаботится о жизненном цикле этого класса, поскольку он регистрируется как сервис.
Затем в вашем контроллере вы можете автоматически подключить (создать экземпляр) его и использовать его функциональность:
источник
Внедрение зависимостей Spring поможет вам удалить связь из ваших классов. Вместо создания объекта, подобного этому:
Вы будете использовать это после введения DI:
Для достижения этого вам необходимо создать в вашем
ServiceConfiguration
файле компонент вашего сервиса . После этого вам нужно импортировать этотServiceConfiguration
класс в вашWebApplicationConfiguration
класс, чтобы вы могли автоматически связывать этот bean-компонент с вашим контроллером следующим образом:Вы можете найти пример POC на основе конфигурации Java здесь .
источник
Стандартный способ:
Пользовательский интерфейс сервиса:
Класс UserServiceImpl:
Вывод:
Example test UserServiceImpl
Это отличный пример тесно связанных классов, плохой пример дизайна, и возникнут проблемы с тестированием (PowerMockito также плох).
Теперь давайте посмотрим на внедрение зависимостей SpringBoot, хороший пример слабой связи:
Интерфейс остается прежним,
Основной класс:
Класс ServiceUserImpl:
Вывод:
Example test UserServiceImpl
и теперь легко написать тест:
Я показал
@Autowired
аннотацию на конструкторе, но она также может быть использована на установщике или поле.источник
Вся концепция инверсии управления означает, что вы свободны от рутинной работы по созданию экземпляров объектов вручную и предоставлению всех необходимых зависимостей. Когда вы аннотируете класс соответствующей аннотацией (например
@Service
), Spring автоматически создаст экземпляр объекта для вас. Если вы не знакомы с аннотациями, вы также можете использовать XML-файл. Однако неплохо было бы создавать экземпляры классов вручную (сnew
ключевым словом) в модульных тестах, когда вы не хотите загружать весь контекст Spring.источник
Помните, что вы должны включить
@Autowired
аннотацию, добавив элемент<context:annotation-config/>
в конфигурационный файл Spring. Это зарегистрирует тот,AutowiredAnnotationBeanPostProcessor
который заботится об обработке аннотации.И тогда вы можете автоматически подключить свой сервис, используя метод полевого ввода.
Я нашел это из поста Spring @autowired аннотации
источник
Есть 3 способа, которыми вы можете создать экземпляр, используя
@Autowired
.1.
@Autowired
на свойстваАннотация может использоваться непосредственно для свойств, поэтому устраняется необходимость в методах получения и установки:
В приведенном выше примере Spring ищет и вводит,
userService
когдаUserController
создается.2.
@Autowired
на сеттеров@Autowired
Аннотации можно использовать на сеттерах. В приведенном ниже примере, когда аннотация используется в методе setter, метод setter вызывается с экземпляромuserService
когдаUserController
создается:3.
@Autowired
на конструкторах@Autowired
Аннотации также могут быть использованы на конструкторах. В приведенном ниже примере, когда аннотация используется в конструкторе, экземплярuserService
создается в качестве аргумента конструктора приUserController
его создании:источник
Проще говоря, Autowiring, проводка ссылок автоматически, теперь встает вопрос, кто это делает и какой тип подключения. Ответ: Контейнер делает это, и вторичный тип проводки поддерживается, примитивы должны быть сделаны вручную.
Вопрос: Как контейнер знает, какой тип проводки?
Ответ: Мы определяем это как byType, byName, конструктор.
Вопрос: Есть ли способ, которым мы не определяем тип автопроводки?
Ответ: Да, это делается с помощью одной аннотации, @Autowired.
Вопрос: Но как система знает, мне нужно выбрать этот тип вторичных данных?
Ответ: Вы предоставите эти данные в своем файле spring.xml или с помощью аннотаций стереотипов для своего класса, чтобы контейнер мог сам создавать объекты для вас.
источник