我正在尝试实例化一个组件对象,我<bean>
在 applicationContext.xml 中为其声明了条目。实例化我的目标组件类的流程如下
计算控制器 -> 计算服务 -> 计算组件
在哪里
CalculatorController - 范围 = 请求,使用 @Controller 注释并包含在 webapplicationContext.xml 中的组件扫描中
CalculatorService - Scope = 单例,使用 @service 注释并包含在 applicationContext.xml 中的组件扫描中
CalculateComponent - 范围 = 请求,无注释,从 webapplicationConext.xml 和 applicationContext.xml 中的组件扫描中排除。在 webApplicationContext.xml 中定义了 bean 条目,范围 = 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 有一个 3 参数 ref 对象构造函数,它们三个都<bean>
在 webApplicationContext.xml 中具有单例范围的条目,并且它们没有注释。
当请求发送创建CalculateComponent对象时,spring容器抛出如下错误。
“未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,那么您的代码是可能在 DispatcherServlet/DispatcherPortlet 之外运行:在这种情况下,使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。”
请指教。
更新:
当我从 contextConfigLocation 中删除 /WEB-INF/mvc-dispatcher-servlet.xml 并启动服务器时,我得到了 Autowired failed 错误 - “No qualifying bean of type of CalculateComponent found for dependency:”,即使在我从请求中更改了范围之后到单身。
然后我在CalculateService 中注释掉了CalculateComponent 的自动装配,我现在可以看到CalculateComponent 启动了两次(如我的@Serge Ballesta 所述)。所以我得出的结论是,CalculateService 是通过 ContextLoaderListener(applicationContext.xml 中的 bean 条目)在加载 DispatcherServlet 之前启动的(即没有加载 mvc-dispatcher-servlet 中提到的 bean)。
我在 contextConfigLocation 中再次添加了 /WEB-INF/mvc-dispatcher-servlet.xml,但这次是作为第一个条目(即在 applicationContext.xml 之上)。现在,CalculateComponent 再次加载了两次,并且自动装配是在单例范围内完成的。通过此设置,我将CalculateComponent 范围更改回request,但再次出现“我得到No thread-bound request found”错误。
所以问题是,
ContextLoaderListener 试图在 DispatcherServlet(CalculateComponent) 加载/可用之前对其资源进行初始化。