«1. Обзор
В этом руководстве мы узнаем о различиях между двумя основными элементами конфигурации XML Spring: \u003ccontext:annotation-config\u003e и \u003ccontext:component-scan\u003e.
2. Определения бинов
Как мы все знаем, Spring предоставляет нам два способа определения наших бинов и зависимостей: конфигурация XML и аннотации Java. Мы также можем разделить аннотации Spring на две группы: аннотации внедрения зависимостей и аннотации bean-компонентов.
До аннотаций нам приходилось вручную определять все наши bean-компоненты и зависимости в файлах конфигурации XML. Теперь, благодаря аннотациям Spring, он может автоматически обнаруживать и связывать все наши bean-компоненты и зависимости для нас. Таким образом, мы можем, по крайней мере, исключить XML, необходимый для bean-компонентов и зависимостей.
Однако мы должны помнить, что аннотации бесполезны, если мы их не активируем. Чтобы активировать их, мы можем добавить либо \u003ccontext:annotation-config\u003e, либо \u003ccontext:component-scan\u003e поверх нашего XML-файла.
В этом разделе мы увидим, чем \u003ccontext:annotation-config\u003e и \u003ccontext:component-scan\u003e отличаются друг от друга с точки зрения способов активации аннотаций.
3. Активация аннотации с помощью \u003ccontext:annotation-config\u003e
Аннотация \u003ccontext:annotation-config\u003e в основном используется для активации аннотаций внедрения зависимостей. @Autowired, @Qualifier, @PostConstruct, @PreDestroy и @Resource — вот некоторые из тех, которые может разрешить \u003ccontext:annotation-config\u003e.
Давайте рассмотрим простой пример, чтобы увидеть, как \u003ccontext:annotation-config\u003e может упростить нам настройку XML.
Во-первых, давайте создадим класс с полем зависимости:
public class UserService {
@Autowired
private AccountService accountService;
}
public class AccountService {}
<bean id="accountService" class="AccountService"></bean>
<bean id="userService" class="UserService"></bean>
Теперь давайте определим наши bean-компоненты.
Прежде чем идти дальше, давайте отметим, что нам все еще нужно объявить bean-компоненты в XML. Это связано с тем, что \u003ccontext:annotation-config\u003e активирует аннотации только для bean-компонентов, уже зарегистрированных в контексте приложения.
Как видно здесь, мы аннотировали поле accountService с помощью @Autowired. @Autowired сообщает Spring, что это поле является зависимостью, которая должна быть автоматически подключена соответствующим bean-компонентом.
<bean id="userService" class="UserService">
<property name="accountService" ref="accountService"></property>
</bean>
Если бы мы не использовали @Autowired, нам нужно было бы установить зависимость accountService вручную:
@Test
public void givenContextAnnotationConfig_whenDependenciesAnnotated_thenNoXMLNeeded() {
ApplicationContext context
= new ClassPathXmlApplicationContext("classpath:annotationconfigvscomponentscan-beans.xml");
UserService userService = context.getBean(UserService.class);
AccountService accountService = context.getBean(AccountService.class);
Assert.assertNotNull(userService);
Assert.assertNotNull(accountService);
Assert.assertNotNull(userService.getAccountService());
}
Теперь мы можем ссылаться на наши bean-компоненты и зависимости в модульном тесте:
<context:annotation-config/>
Хм, что-то здесь не так. Похоже, Spring не подключает accountService, хотя мы аннотировали его @Autowired. Похоже, @Autowired не активен. Чтобы решить эту проблему, мы просто добавим следующую строку поверх нашего XML-файла:
4. Активация аннотации с помощью \u003ccontext:component-scan\u003e
Аналогично \u003ccontext:annotation -config\u003e, \u003ccontext:component-scan\u003e также может распознавать и обрабатывать аннотации внедрения зависимостей. Более того, \u003ccontext:component-scan\u003e распознает аннотации компонентов, которые \u003ccontext:annotation-config\u003e не обнаруживает.
По сути, \u003ccontext:component-scan\u003e обнаруживает аннотации путем сканирования пакетов. Другими словами, он сообщает Spring, какие пакеты необходимо сканировать для поиска аннотированных bean-компонентов или компонентов.
@Component, @Repository, @Service, @Controller, @RestController и @Configuration — это несколько объектов, которые может обнаружить \u003ccontext:component-scan\u003e.
@Component
public class UserService {
@Autowired
private AccountService accountService;
}
@Component
public class AccountService {}
Теперь давайте посмотрим, как мы можем упростить наш предыдущий пример:
<context:component-scan
base-package="com.baeldung.annotationconfigvscomponentscan.components" />
Здесь аннотация @Component помечает наши классы как bean-компоненты. Теперь мы можем удалить все определения bean-компонентов из нашего XML-файла. И, конечно же, нам нужно держать \u003ccontext:component-scan\u003e поверх него:
Наконец, давайте отметим, что Spring будет искать аннотированные bean-компоненты и зависимости в пакете, указанном в base-package. атрибут.
5. Заключение