1. Фон
Недавно из-за проблем с сканированием пакетов проекта в процессе решения проблемы я случайно обнаружил, что Spring и SpringMVC имеют контейнерные отношения между родителями и детьми, и именно из-за этого часто возникает проблема сканирования пакетов. Здесь мы анализируем и понимаем взаимосвязь контейнеров между родительским ребенком между Spring и SpringMVC и даем официальный рекомендуемый способ сканирования пакетов в файлах конфигурации Spring и SpringMVC.
2. Понимание концепции и знания закладывают основу
В основной концепции общей структуры Spring контейнеры являются основной идеей, которая используется для управления всем жизненным циклом бобов. В проекте не обязательно есть только один контейнер. Пружина может включать несколько контейнеров, а контейнер имеет верхние и нижние уровни. Наиболее распространенный сценарий в настоящее время - представить две рамки Spring и Springmvc в проекте. Тогда это на самом деле два контейнера. Весна является родительским контейнером, а Springmvc - это детский контейнер. Бобовой, зарегистрированный в родительском контейнере Spring, видны контейнеру SpringMVC, в то время как бобы, зарегистрированные в контейнере SpringMVC, являются невидимыми для родительского контейнера Spring, то есть дочерний контейнер может видеть зарегистрированный боб в родительском контейнере, иначе он не будет работать.
Мы можем использовать конфигурацию Unified Annotation следующим образом для регистрации бобов, не настраивая каждый фасоль с использованием XML отдельно.
<Контекст: компонент-сканирование base-package = "com.hafiz.www" />
Из справочного руководства, предоставленного весной, мы знаем, что функция этой конфигурации состоит в том, чтобы сканировать все классы под настроенным пакетом базового пакета, которые используют аннотацию @Component, и автоматически регистрируют их в контейнере. В то же время они также сканируют три аннотации @Controller, @Service и @Respository, потому что они унаследованы от @Component.
В проекте мы часто видим следующую конфигурацию. Фактически, с приведенной выше конфигурацией, это может быть опущено, поскольку вышеуказанная конфигурация по умолчанию будет включать следующую конфигурацию. В следующей конфигурации будут объявлены такие аннотации, как @Required, @Autowired, @postconstruct, @persistencecontext, @resource, @predestroy и т. Д. По умолчанию.
<Контекст: аннотация-конфиг/>
Кроме того, существует еще одна конфигурация, связанная с SpringMVC. После проверки это должно быть настроено для SpringMVC, поскольку он объявляет @Requestmapping, @Requestbody, @Responsebody и т. Д. Более того, эта конфигурация загружает множество методов привязки параметров по умолчанию, таких как анализатор преобразования JSON.
<MVC: Annotation-управляемый />
Версия на конфигурации выше предложения до весны 3.1 эквивалентна следующему методу конфигурации
<!-Настройте Mapper контроллера аннотаций, он используется в Springmvc для картирования URL-адреса запроса на конкретный контроллер-> <Bean/> <!-Настройка Annation Controller Mapper, он используется в Springmvc для карты конкретных запросов на конкретный метод-> <Bean/>>
Версия после Spring3.1 эквивалентна следующим методам конфигурации
<!-Настройте Mapper контроллера аннотаций, он используется в Springmvc для картирования URL-адреса запроса на конкретный контроллер-> <Bean/> <!-Настройка Annation Controller Mapper, он используется в Springmvc для карты конкретных запросов на конкретный метод-> <Bean/>>
3. Конкретный анализ сценариев
Давайте внимательно рассмотрим причины конфликта контейнера между Spring и Springmvc?
У нас есть два контейнера, Spring и Springmvc, а их файлы конфигурации являются ApplicationContext.xml и ApplicationContext-Mvc.xml соответственно.
1. The Context: Component Scan Base-package = "com.hafiz.www" /> настроен в ApplicationContext.xml, чтобы нести ответственность за сканирование и регистрацию всех бобов, которые необходимо зарегистрировать.
2. Настройка <mvc: annotation-raven /> в ApplicationContext-Mvc.xml, чтобы нести ответственность за использование аннотаций, связанных с SpringMVC.
3. При запуске проекта мы обнаружили, что SpringMVC не может прыгнуть. Мы установили уровень печати журнала для отладки для отладки. Мы обнаружили, что запросы в контейнере SpringMVC, похоже, не отображаются с конкретным контроллером.
4. Configure <Context: Component Scan Base-package = "com.hafiz.www" /> в ApplicationContext-MVC.xml. После перезапуска проверка является успешной, а прыжок SpringMVC действителен.
Давайте проверим конкретную причину, посмотрите на исходный код и начнем с DispatcherServlet Springmvc для поиска. Мы обнаружили, что когда SpringMVC будет инициализирован, мы будем искать все бобы в контейнере SpringMVC, которые используют аннотацию @Controller, чтобы определить, является ли это обработчиком. Двухступенчатая конфигурация 1 и 2 делает текущий контейнер SpringMVC не регистрировать боб с аннотацией @Controller, но все бобы с аннотацией @Controller зарегистрированы в родительском контейнере пружины, поэтому SpringMVC не может найти процессор и не может прыгнуть. Основной исходный код заключается в следующем:
Protected void inithandlerMethods () {if (logger.isdebugenabled ()) {logger.debug ("ищет сопоставления запросов в контексте приложения:" + getApplicationContext ()); } String [] beannames = (this.detecthandlermethodsinancestorcontexts? Beanfactoryutils.beannamesfortypeincludedancestors (getApplicationContext (), Object.Class): getApplicationContext (). GetBeanNamesFortyPe (Object.Class)); for (string beanname: beannames) {if (ishandler (getApplicationContext (). getType (beanname))) {detecthandlermethods (beanname); }} handlermethodsinitialize (gethandlermethods ());}В методе Ishandler мы определим, является ли аннотация текущего боба контроллером. Исходный код заключается в следующем:
Защищенный логический ishandler (class <?> beantype) {return annotationutils.findannotation (beantype, controller.class)! = null;}В 4 -й ступенчатой конфигурации все бобы с аннотацией @Controller также зарегистрированы в контейнере SpringMVC, поэтому SpringMVC может найти процессор для обработки, поэтому он нормально прыгает.
Мы нашли причину, по которой он не может прыгнуть правильно, так в чем его решение?
Мы заметили, что в методе inithandlermethods () выключатель detecthandlermethodsinancestorcontexts, он в основном управляет, которые получают бобы в контейнере и включен ли родительский контейнер. Он не включен по умолчанию. Таким образом, решение состоит в том, чтобы настроить свойство detecthandlermethodsinancestorcontexts of handlermapping true в файле конфигурации Springmvc (здесь вам необходимо увидеть, какой тип ручной работы используется в соответствии с конкретным проектом), чтобы он мог обнаружить бобов родительского контейнера. следующее:
<Bean> <name = name = "detecthandlermethodsinancestorContexts"> <dure> true </value> </property> </bean>
Однако в реальных проектах будет много конфигураций. Мы разделяем различные типы бобов в разных контейнерах в соответствии с официальными рекомендациями в соответствии с различными бизнес -модулями: родительский контейнер Spring отвечает за регистрацию всех других бобов, которые не аннотируются @Controller, в то время как SpringMVC отвечает только за регистрацию бобов, аннотированные @Controller, поэтому они предполагают свои собственные обязанности и проясняют границы. Метод конфигурации следующим образом
1. Конфигурирование в ApplicationContext.xml:
<!-Зарегистрируйте бобы в весенних контейнерах, которые не аннотируются @Controller-> <Контекст: компонент-сканирование Base-package = "com.hafiz.www"> <context: Exclude-Filter type = "annotation" Expression = "org.springframework.steretype.controller"/> </context: componte-scan>
2. Конфигурация в ApplicationContext-Mvc.xml
<!-- Only beans with @controller annotation are registered in SpringMVC container --><context:component-scan base-package="com.hafiz.www" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.steretype.Controller" /></context:component-scan>
3. Резюме
Таким образом, после того, как мы поняли взаимосвязь между родительским и ребенком между весной и SpringMVC и принцип сканирования и регистрации, согласно официальным предложениям, мы можем выделить различные виды бобов на различные контейнеры для управления. Если есть проблемы, такие как бобы, нельзя найти, SpringMVC не может быть перенаправлен, а конфигурация транзакции не удается, мы можем быстро найти и решить проблему. Очень счастлив, есть ли ~
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.