Я пытаюсь создать экземпляр объекта компонента, для которого я объявил запись <bean>
в applicationContext.xml. Поток создания экземпляра моего целевого класса компонентов выглядит следующим образом
CalculateController -> CalculateService -> CalculateComponent
Где
CalculatorController — scope = request, аннотированный @Controller и включенный в сканирование компонентов в webapplicationContext.xml
CalculatorService — Scope = singleton, аннотированный @service и включенный в сканирование компонентов в applicationContext.xml
CalculateComponent — область действия = запрос, без аннотации, исключено из сканирования компонентов как в webapplicationConext.xml, так и в applicationContext.xml. Определенная запись bean-компонента в webApplicationContext.xml с областью видимости = request. Также включите <aop:scoped-proxy/>
в определение <bean>
.
Я включил следующую запись в web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/applicationContext.xml
/WEB-INF/mvc-dispatcher-servlet.xml
....Other resource xmls
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- To retrieve session related information -->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
обратите внимание, что CalculateComponent имеет конструктор объекта ref с 3 параметрами, и все три из них имеют запись <bean>
в webApplicationContext.xml с одноэлементной областью действия, и они не аннотированы.
Когда запрос отправляется для создания объекта CalculateComponent, контейнер Spring выдает следующую ошибку.
«Запрос, связанный с потоком, не найден: вы ссылаетесь на атрибуты запроса вне фактического веб-запроса или обрабатываете запрос вне исходного потока получения? Если вы фактически работаете в веб-запросе и все еще получаете это сообщение, ваш код вероятно, работает за пределами DispatcherServlet/DispatcherPortlet: в этом случае используйте RequestContextListener или RequestContextFilter, чтобы открыть текущий запрос».
Пожалуйста, порекомендуйте.
Обновление:
Когда я удалил /WEB-INF/mvc-dispatcher-servlet.xml из contextConfigLocation и запустил сервер, я получил ошибку Autowired failed — «Нет подходящего bean-компонента типа CalculateComponent для зависимости:», даже после того, как я изменил область запроса к синглтону.
Затем я прокомментировал автопроводку CalculateComponent в CalculateService, и теперь я вижу, что CalculateComponent инициирован дважды (как упоминалось в моем @Serge Ballesta). Итак, я пришел к выводу, что CalculateService инициируется через ContextLoaderListener (запись bean-компонента в applicationContext.xml) до загрузки DispatcherServlet (т.е. bean-компонент, упомянутый в mvc-dispatcher-servlet, не загружен).
Я снова добавил /WEB-INF/mvc-dispatcher-servlet.xml в contextConfigLocation, но на этот раз в качестве первой записи (т. е. поверх applicationContext.xml). Теперь CalculateComponent снова загружается дважды, и Autowiring выполняется с одноэлементной областью видимости. С помощью этой настройки я изменил область CalculateComponent обратно на запрос, но снова «Я получил ошибку «Нет запроса, привязанного к потоку».
Итак, проблема в том,
ContextLoaderListener пытается инициировать ресурсы DispatcherServlet (CalculateComponent) до его загрузки/доступности.