Я изучаю Spring 3, и я, кажется, не понимаю функциональности позади <context:annotation-config>
и <context:component-scan>
.
Из того, что я читал , они , кажется, работать с различными аннотаций ( @Required
, и @Autowired
т.д. против @Component
, @Repository
, и @Service
т.д.), но и от того, что я прочитал они регистрируют те же боб постпроцессор классов.
Для того, чтобы запутать меня еще больше, есть annotation-config
атрибут на <context:component-scan>
.
Может кто-нибудь пролить свет на эти метки? Что похоже, что отличается, одно вытесняется другим, они дополняют друг друга, нужен ли мне один из них, оба?
java
spring
configuration
annotations
spring-3
user938214097
источник
источник
component-scan
возможности.Ответы:
<context:annotation-config>
используется для активации аннотаций в bean-компонентах, уже зарегистрированных в контексте приложения (независимо от того, были ли они определены с помощью XML или путем сканирования пакетов).<context:component-scan>
может также делать то, что<context:annotation-config>
делает, но<context:component-scan>
также сканирует пакеты, чтобы найти и зарегистрировать bean-компоненты в контексте приложения.Я буду использовать некоторые примеры, чтобы показать различия / сходства.
Давайте начнем с базовой настройки трех bean-компонентов типа
A
,B
а такжеC
сB
иC
вводимых вA
.Со следующей конфигурацией XML:
Загрузка контекста производит следующий вывод:
ОК, это ожидаемый результат. Но это «старый стиль» весны. Теперь у нас есть аннотации, поэтому давайте используем их для упрощения XML.
Во-первых, давайте автоматически подключим свойства
bbb
и к бину следующим образом:ccc
A
Это позволяет мне удалить следующие строки из XML:
Мой XML теперь упрощен до этого:
Когда я загружаю контекст, я получаю следующий вывод:
ОК, это неправильно! Что случилось? Почему мои свойства не подключены автоматически?
Ну, аннотации - хорошая особенность, но сами по себе они ничего не делают. Они просто комментируют вещи. Вам нужен инструмент обработки, чтобы найти аннотации и что-то с ними сделать.
<context:annotation-config>
для спасения. Это активирует действия для аннотаций, которые он находит в bean-компонентах, определенных в том же контексте приложения, где он определен.Если я изменю свой XML на это:
когда я загружаю контекст приложения, я получаю правильный результат:
Хорошо, это хорошо, но я удалил две строки из XML и добавил одну. Это не очень большая разница. Идея с аннотациями состоит в том, что он должен удалить XML.
Итак, давайте удалим определения XML и заменим их все аннотациями:
Пока в XML мы сохраняем только это:
Мы загружаем контекст, и результат ... ничего. Бины не создаются, бобы не подключаются автоматически. Ничего!
Это потому, что, как я сказал в первом абзаце,
<context:annotation-config />
единственные работы с bean-компонентами, зарегистрированными в контексте приложения. Поскольку я удалил конфигурацию XML для трех компонентов, он не создан и<context:annotation-config />
не имеет «целей» для работы.Но это не будет проблемой, из-за
<context:component-scan>
которой можно сканировать пакет на предмет «целей» для работы. Давайте изменим содержимое XML-конфигурации на следующую запись:Когда я загружаю контекст, я получаю следующий вывод:
Хм ... чего-то не хватает. Почему?
Если вы внимательно присмотритесь к классам, у класса
A
есть пакет,com.yyy
но я указал в<context:component-scan>
пакете для использования,com.xxx
так что это полностью пропустило мойA
класс и только поднялоB
иC
которые находятся вcom.xxx
пакете.Чтобы это исправить, я добавляю и другой пакет:
и теперь мы получаем ожидаемый результат:
И это все! Теперь у вас больше нет определений XML, у вас есть аннотации.
В качестве последнего примера, сохраняя аннотированные классы
A
,B
аC
и добавив следующее в XML, то , что мы получим после загрузки контекста?Мы все еще получаем правильный результат:
Даже если bean-компонент для класса
A
не получен сканированием, инструменты обработки все равно применяются<context:component-scan>
ко всем bean-компонентам, зарегистрированным в контексте приложения, даже дляA
которых был зарегистрирован вручную в XML.Но что, если у нас будет следующий XML, получим ли мы дублированные бины, потому что мы указали оба
<context:annotation-config />
и<context:component-scan>
?Нет, дубликатов нет, мы снова получаем ожидаемый результат:
Это связано с тем, что оба тега регистрируют одни и те же инструменты обработки (
<context:annotation-config />
могут быть опущены, если<context:component-scan>
указано), но Spring заботится о запуске их только один раз.Даже если вы зарегистрируете инструменты обработки несколько раз, Spring по-прежнему будет проверять их действие только один раз; этот XML:
будет по-прежнему генерировать следующий результат:
Хорошо, это насчет рэпа.
Я надеюсь, что эта информация вместе с ответами @Tomasz Nurkiewicz и @Sean Patrick Floyd - все, что вам нужно, чтобы понять, как
<context:annotation-config>
и как<context:component-scan>
работать.источник
Я нашел это хорошее резюме, какие аннотации подобраны какими объявлениями. Изучив его, вы обнаружите, что он
<context:component-scan/>
распознает расширенный набор аннотаций<context:annotation-config/>
, а именно:@Component
,@Service
,@Repository
,@Controller
,@Endpoint
@Configuration
,@Bean
,@Lazy
,@Scope
,@Order
,@Primary
,@Profile
,@DependsOn
,@Import
,@ImportResource
Как вы можете видеть,
<context:component-scan/>
логически расширяет возможности<context:annotation-config/>
компонента CLASSPATH и функции Java @Configuration.источник
Spring позволяет делать две вещи:
1. Автопроводка
Обычно в applicationContext.xml вы определяете компоненты, а другие компоненты подключаются с помощью методов конструктора или сеттера. Вы можете связывать бины, используя XML или аннотации. Если вы используете аннотации, вам нужно активировать аннотации и добавить
<context:annotation-config />
в applicationContext.xml . Это упростит структуру тега из applicationContext.xml , потому что вам не придется вручную связывать компоненты (конструктор или установщик). Вы можете использовать@Autowire
аннотацию, и бобы будут подключены по типу.Шаг вперед для избежания ручной настройки XML
2. Автообнаружение
Автообнаружение упрощает XML еще на один шаг, в том смысле, что вам даже не нужно добавлять
<bean>
тег в applicationContext.xml . Вы просто помечаете определенные bean-компоненты одной из следующих аннотаций, и Spring автоматически подключает помеченные bean-компоненты и их зависимости в контейнер Spring. Аннотации следующие: @Controller , @Service , @Component , @Repository . Используя<context:component-scan>
и указывая базовый пакет, Spring автоматически обнаружит и подключит компоненты к контейнеру Spring.В заключение:
<context:annotation-config />
используется для того, чтобы иметь возможность использовать аннотацию @Autowired<context:component-scan />
используется для определения поиска конкретных бинов и попытки автопроводки.источник
<context:annotation-config>
активирует множество различных аннотаций в bean-компонентах, независимо от того, определены они в XML или путем сканирования компонентов.<context:component-scan>
для определения бинов без использования XMLДля получения дополнительной информации читайте:
источник
<context:component-scan>
я не смогу переопределить определение бина, используя XML?<context:component-scan>
? Потеряю ли я что-то, если не пользуюсь<context:annotation-config>
?Разница между ними действительно проста!
Позволяет использовать аннотации, которые ограничены подключением свойств и конструкторов только для bean-компонентов!
В то время как
Включает все , что
<context:annotation-config />
можно сделать, с добавлением использования стереотипов , например , ..@Component
,@Service
,@Repository
. Таким образом, вы можете связывать целые бины, а не ограничиваться только конструкторами или свойствами!источник
<context:annotation-config>
: Сканирование и активация аннотаций для уже зарегистрированных bean-компонентов в весеннем config xml.<context:component-scan>
: Регистрация бобов +<context:annotation-config>
@Autowired и @Required являются целевыми уровнями свойств, поэтому bean должен быть зарегистрирован весной IOC перед использованием этих аннотаций. Чтобы включить эти аннотации, нужно либо зарегистрировать соответствующие бины, либо включить
<context:annotation-config />
. т.е.<context:annotation-config />
работает только с зарегистрированными бобами.@Required включает
RequiredAnnotationBeanPostProcessor
инструмент обработки@Autowired включает
AutowiredAnnotationBeanPostProcessor
инструмент обработкиПримечание. Сама аннотация не имеет ничего общего, нам нужен инструмент обработки , который является классом внизу и отвечает за основной процесс.
@Repository, @Service и @Controller являются @Component , и они нацелены на уровень класса .
<context:component-scan>
он сканирует пакет и находит и регистрирует компоненты, а также включает в себя работу, проделанную<context:annotation-config />
.Перенос XML в аннотации
источник
<context:annotation-config>
Тег сообщает Spring для сканирования кодового для автоматического разрешения зависимостей требований классов , содержащих @Autowired аннотации.В Spring 2.5 также добавлена поддержка аннотаций JSR-250, таких как @Resource, @PostConstruct и @ PreDestroy. Использование этих аннотаций также требует регистрации определенных BeanPostProcessors в контейнере Spring. Как всегда, они могут быть зарегистрированы как отдельные определения bean-компонентов, но они также могут быть неявно зарегистрированы путем включения
<context:annotation-config>
тега в конфигурацию Spring.Взято из Spring документации о конфигурации на основе аннотаций
Spring предоставляет возможность автоматического обнаружения «стереотипных» классов и регистрации соответствующих BeanDefinitions с помощью ApplicationContext.
Согласно javadoc org.springframework.stereotype :
Стереотипы - это аннотации, обозначающие роли типов или методов в общей архитектуре (на концептуальном уровне, а не на уровне реализации). Пример: @Controller @Service @Repository и т. Д. Они предназначены для использования инструментами и аспектами (что делает идеальную цель для точечных копий).
Для автоматического определения таких «стереотипных» классов необходим
<context:component-scan>
тег.Этот
<context:component-scan>
тег также указывает Spring сканировать код на наличие бобов для инъекций в указанном пакете (и всех его подпакетах).источник
Только разлагает
@Autowired
и@Qualifer
аннотации, это все, что о Injection Dependency , Есть другие аннотации , которые делают ту же работу, я думаю , как@Inject
, но все это приведет к Resolve DI через аннотацию.Имейте в виду
<context:annotation-config>
, что даже когда вы объявили элемент, вы все равно должны объявить свой класс как Bean, помните, что у нас есть три доступных варианта<bean>
Теперь с
Это делает две вещи:
<context:annotation-config>
делает.Поэтому, если вы заявляете
<context:component-scan>
, больше не нужно объявлять<context:annotation-config>
тоже.Это все
Распространенным сценарием было, например, объявить только bean-компонент через XML и разрешить DI с помощью аннотаций, например.
Мы только объявили bean-компоненты, ничего о
<constructor-arg>
и<property>
DI настраивается в их собственных классах через @Autowired. Это означает, что Сервисы используют @Autowired для своих компонентов Repositories, а Репозитории используют @Autowired для JdbcTemplate, DataSource и т.д..componentsисточник
попробуйте
<context:component-scan base-package="..." annotation-config="false"/>
, в вашей конфигурации @Service, @Repository, @Component работает нормально, но @ Autowired, @ Resource и @Inject не работают.Это означает, что AutowiredAnnotationBeanPostProcessor не будет включен, и контейнер Spring не будет обрабатывать аннотации Autowiring.
источник
Другим важным моментом, который следует отметить, является то, что
context:component-scan
неявно вызываетсяcontext:annotation-config
для активации аннотаций на bean-компонентах. Ну, если вы не хотитеcontext:component-scan
неявно активировать аннотации для вас, вы можете продолжить установку элемента annotation-config дляcontext:component-scan
tofalse
.Обобщить:
источник
<context:component-scan base-package="package name" />
:Это используется, чтобы сообщить контейнеру, что в моем пакете есть классы bean-компонентов, которые сканируют эти классы bean-компонентов. Чтобы сканировать классы bean-компонентов по контейнеру поверх bean-компонента, нам нужно написать одну из аннотаций стереофонического типа, как показано ниже.
@Component
,@Service
,@Repository
,@Controller
<context:annotation-config />
:Если мы не хотим явно писать тег bean в XML, тогда как контейнер узнает, есть ли в bean автоматическое подключение. Это возможно с помощью
@Autowired
аннотации. мы должны сообщить контейнеру, что в моем бобе есть автоматическая проводкаcontext:annotation-config
.источник
<context:component-scan/>
Пользовательские теги регистрируют тот же набор бин как это делаются, помимо своей основной ответственности за сканирование пакетов Java и регистрации определений боба из пути к классам.Если по какой-то причине следует избегать этой регистрации определений bean-компонентов по умолчанию, то для этого нужно указать дополнительный атрибут «annotation-config» в компонентном сканировании следующим образом:
Ссылка: http://www.java-allandsundry.com/2012/12/contextcomponent-scan-contextannotation.html
источник
<context:annotation-config>
:Это говорит Spring, что я собираюсь использовать Annotated bean-компоненты в качестве Spring-bean-компонентов, и они будут подключаться через
@Autowired
аннотацию вместо объявления в Spring config xml file.<context:component-scan base-package="com.test...">
:Это сообщает контейнеру Spring, с чего начать поиск аннотированных бинов. Здесь весна будет искать все подпакеты базового пакета.
источник
Вы можете найти больше информации в файле контекста Spring. следующее находится в spring-context-4.3.xsd
источник
В качестве дополнения, вы можете использовать
@ComponentScan
для<context:component-scan>
аннотации.Это также описано на spring.io
Стоит отметить, что если вы используете Spring Boot, @Configuration и @ComponentScan могут подразумеваться с помощью аннотации @SpringBootApplication.
источник