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 .