Перейти к основному содержимому

Разница между <context:annotation-config> и <context:component-scan>

· 3 мин. чтения

1. Обзор

В этом руководстве мы узнаем о различиях между двумя основными элементами конфигурации XML Spring: <context:annotation-config> и <context:component-scan> .

2. Определения компонентов

Как мы все знаем, Spring предоставляет нам два способа определения наших bean -компонентов и зависимостей: конфигурация XML и аннотации Java. Мы также можем разделить аннотации Spring на две группы: аннотации внедрения зависимостей и аннотации bean -компонентов .

До аннотаций нам приходилось вручную определять все наши bean-компоненты и зависимости в файлах конфигурации XML. Теперь, благодаря аннотациям Spring, он может автоматически обнаруживать и связывать все наши bean-компоненты и зависимости для нас . Таким образом, мы можем, по крайней мере, исключить XML, необходимый для bean-компонентов и зависимостей.

Однако мы должны помнить, что аннотации бесполезны, если мы их не активируем . Чтобы активировать их, мы можем добавить либо <context:annotation-config>, либо <context:component-scan> поверх нашего XML-файла.

В этом разделе мы увидим, чем <context:annotation-config> и <context:component-scan> отличаются друг от друга с точки зрения способов активации аннотаций.

3. Активация аннотации с помощью < context:annotation-config>

Аннотация <context:annotation - config> в основном используется для активации аннотаций внедрения зависимостей. @Autowired , @Qualifier , @PostConstruct , @PreDestroy и @Resource — вот некоторые из тех, которые может разрешить <context:annotation-config> .

Давайте сделаем простой пример, чтобы увидеть, как <context:annotation-config> может упростить для нас настройку XML.

Во-первых, давайте создадим класс с полем зависимости:

public class UserService {
@Autowired
private AccountService accountService;
}
public class AccountService {}

Теперь давайте определим наши бобы.

<bean id="accountService" class="AccountService"></bean>

<bean id="userService" class="UserService"></bean>

Прежде чем идти дальше, давайте отметим, что нам все еще нужно объявить bean-компоненты в XML. Это связано с тем, что <context:annotation-config> активирует аннотации только для bean-компонентов, уже зарегистрированных в контексте приложения .

Как видно здесь, мы аннотировали поле accountService с помощью @Autowired . @Autowired сообщает Spring, что это поле является зависимостью, которая должна быть автоматически подключена соответствующим bean-компонентом.

Если бы мы не использовали @Autowired , нам нужно было бы установить зависимость accountService вручную:

<bean id="userService" class="UserService">
<property name="accountService" ref="accountService"></property>
</bean>

Теперь мы можем ссылаться на наши bean-компоненты и зависимости в модульном тесте:

@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());
}

Хм, что-то здесь не так. Похоже, Spring не подключает accountService , хотя мы аннотировали его @Autowired . Похоже, @Autowired не активен. Чтобы решить эту проблему, мы просто добавим следующую строку поверх нашего XML-файла:

<context:annotation-config/>

4. Активация аннотации с помощью < context:component-scan>

Подобно <context:annotation-config> , <context:component-scan> также может распознавать и обрабатывать аннотации внедрения зависимостей. Кроме того, <context:component-scan> распознает аннотации компонентов, которые <context:annotation-config> не обнаруживает .

По сути, <context:component-scan> обнаруживает аннотации путем сканирования пакетов . Другими словами, он сообщает Spring, какие пакеты необходимо сканировать для поиска аннотированных bean-компонентов или компонентов.

@Component , @Repository , @Service , @Controller , @RestController и @Configuration — это несколько объектов, которые <context:component-scan> может обнаружить .

Теперь давайте посмотрим, как мы можем упростить наш предыдущий пример:

@Component
public class UserService {
@Autowired
private AccountService accountService;
}
@Component
public class AccountService {}

Здесь аннотация @Component помечает наши классы как bean -компоненты . Теперь мы можем удалить все определения bean-компонентов из нашего XML-файла. И, конечно же, нам нужно сохранить <context:component-scan> поверх него:

<context:component-scan
base-package="com.foreach.annotationconfigvscomponentscan.components" />

Наконец, отметим, что Spring будет искать аннотированные bean-компоненты и зависимости в пакете, указанном атрибутом base-package .

5. Вывод

В этом руководстве мы рассмотрели различия между <context:annotation-config> и <context:component-scan> .

Примеры кода, как всегда, закончились на GitHub .