0

<bean>applicationContext.xml でエントリを宣言したコンポーネント オブジェクトをインスタンス化しようとしています。ターゲット コンポーネント クラスをインスタンス化するフローは次のとおりです。

CalculateController -> CalculateService -> CalculateComponent

どこ

CalculatorController - スコープ = リクエスト、@Controller で注釈が付けられ、webapplicationContext.xml のコンポーネント スキャンに含まれる

CalculatorService - Scope = singleton、@service で注釈が付けられ、applicationContext.xml のコンポーネント スキャンに含まれる

CalculateComponent - スコープ = リクエスト、注釈なし、webapplicationConext.xml と applicationContext.xml の両方でコンポーネント スキャンから除外されます。scope = request で webApplicationContext.xml に定義された Bean エントリ。<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 には 3 つのパラメーター ref オブジェクト コンストラクターがあり、それらの 3 つすべて<bean>がシングルトン スコープの webApplicationContext.xml にエントリがあり、注釈が付けられていないことに注意してください。

When the request send to create the CalculateComponent object, spring container throwing the following error.

"No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request."

Please advise.

Update:

When I removed /WEB-INF/mvc-dispatcher-servlet.xml from contextConfigLocation and started the server, I got the Autowired failed error - "No qualifying bean of type CalculateComponent found for dependency:", even after I changed the scope from request to singleton.

Then I commented out the Autowiring of CalculateComponent in CalculateService and I can now see the CalculateComponent initiated twice (as mentioned my @Serge Ballesta). So I concluded that the CalculateService is initiated via ContextLoaderListener (bean entry in applicationContext.xml), before the DispatcherServlet is loaded(i.e no bean mentioned in mvc-dispatcher-servlet is loaded).

I added the /WEB-INF/mvc-dispatcher-servlet.xml back again in contextConfigLocation, but this time as the first entry (i.e on top of applicationContext.xml). Now the CalculateComponent loaded twice again and the Autowiring was done with singleton scope. With this setup I changed the CalculateComponent scope back to request, but again "I got the No thread-bound request found" error.

So the issue is,

ContextLoaderListener trying to initiaze the resources of DispatcherServlet(CalculateComponent) before its loaded / available.

4

2 に答える 2

0

私自身の質問に答えます。質問で述べたように、これはリクエスト スコープのコンポーネント Bean を取得するためのフローです。

CalculateController -> CalculateService -> CalculateComponent。

しかし、CalculateController は非同期リクエストによって呼び出されました。非同期リクエスト スレッドから Web スコープ Bean にアクセスできません。

参考:async task executor でリクエストスコープを有効にする方法

于 2015-06-01T20:43:47.490 に答える
0

It is weird to have a request scoped controller ... AFAIK, the framework expects it to be a singleton. Try to put it in a singleton scope.

And I think that you have all beans from /WEB-INF/mvc-dispatcher-servlet.xml instantiated twice :

  • first in root application context as is is declared in global contextConfigLocation
  • next in the servlet application context of the servlet named mvc-dispatcher

You should either rename the file, so it is not loader as a servlet application context, or remove it from root context

于 2015-05-28T14:29:27.780 に答える