【发布时间】:2015-01-21 19:47:09
【问题描述】:
我已阅读 Injecting Jaxb2Marshaller in Spring MVC controller 和 Difference between applicationContext.xml and spring-servlet.xml in Spring Framework 等,但对为什么我的案子不起作用感到困惑。
这是我的应用上下文和 web.xml 中的内容(精简以仅显示相关部分):
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app .... >
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/app-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
....
<servlet>
<servlet-name>spring-rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
...
</web-app>
spring-rest-servlet.xml
<beans ....>
<!-- Only scan for Controllers in Servlet context -->
<context:component-scan base-package="com.fil.ims" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<mvc:annotation-driven />
<context:annotation-config />
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
....
</bean>
</beans>
我有一个类似这样的控制器:
@Controller
public class FooControllerImpl implements FooController {
@Inject
@Named("jaxb2Marshaller")
Jaxb2Marshaller jaxb2Marshaller;
public void setJaxb2Marshaller(Jaxb2Marshaller jaxb2Marshaller) {
this.jaxb2Marshaller = jaxb2Marshaller;
}
//.....
}
我发现我无法在 servlet 上下文中注入 jaxb2Marshaller(抛出NoSuchBeanDefinitionException)。但是,如果我将jaxb2Marshaller 放在主应用程序上下文(app-context.xml)中,则可以正常注入。
我很困惑为什么会这样。据我了解,如果我在web.xml 中有ContextLoaderListener,则提供的上下文配置(app-context.xml)将用于创建顶级应用程序上下文,然后是调度程序servlet 上下文(我的spring-rest-servlet.xml例如)将被创建为顶级应用上下文下的子上下文。
我不明白的是,控制器和要注入的bean(jaxb2Marshaller)都是在调度程序servlet上下文下创建的,为什么我不能将jaxb2Marshaller注入我的FooController? (我知道如果要注入的 bean 位于子应用程序上下文中,它将不起作用,但在这种情况下似乎不是。)
谁能解释一下原因?
更新:
我做了另一个实验(这让我更加困惑),通过在我的控制器中实现ApplicationContextAware,并从控制器中实现applicationContext.getBean("jaxb2Marshaller", Jaxb2Marshaller.class)。返回一个有效的bean(这与我的理解一致)。似乎只有通过注释注入是行不通的。有什么线索吗?
【问题讨论】:
标签: spring spring-mvc