«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. Заключение