我有一个spring-mvc网络应用程序。
以下代码已经过简化和清理,以保护有罪。基本思想是我有两个独立的上下文配置文件:一个用于MVC,另一个用于一般配置文件。
当Spring开始连接控制器时,我得到:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.ConfigBean com.example.ConfigController.config; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.example.ConfigBean] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
但是,来自另一个servlet的以下代码可以正常工作:
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
ConfigBean config = context.getBean(ConfigBean.class);
这告诉我MVC组件扫描程序由于某种原因无法看到配置文件。我试过添加
<import resource="config.xml" />
到dispatcher-servlet.xml
,但没有任何区别。不管怎样,感觉不对,因为我不想要配置bean的两个实例。即使手动将ConfigBean声明复制到dispatcher.xml也无法解决我的问题,这表明我正在做一些非常愚蠢的事情。关于我可能缺少什么的任何建议?
我的详细配置如下:
的web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
/WEB-INF/config.xml
</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
... Some other non-spring stuff ...
</web-app>
调度-servlet.xml中
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:annotation-config />
<context:component-scan base-package="com.example" />
<mvc:annotation-driven />
</beans>
类路径:config.xml中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean class="com.example.ConfigBean">
<property name="foo" value="bar" />
</bean>
</beans>
ConfigController.java
package com.example;
import com.example.ConfigBean
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/config")
public class ConfigController {
@Autowired
private ConfigBean config;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody ConfigBean getConfig() {
return config;
}
}
答案 0 :(得分:2)
可能是因为您已将/WEB-INF/dispatcher-servlet.xml
添加到contextConfigLocation
中的context-param
。
这不是必需的,因为Web应用程序上下文将基于displater servlet名称
准备好文件初始化DispatcherServlet后,Spring MVC会查找 在您的WEB-INF目录中命名为[servlet-name] -servlet.xml的文件 Web应用程序并创建在那里定义的bean,覆盖 全局中使用相同名称定义的任何bean的定义 范围。
答案 1 :(得分:1)
我认为由于存在多个ConfigBean bean实例,自动装配失败了。错误消息有点令人困惑。如果缺少bean或者有多个实例,则会出现相同的错误。
问题在于dispatcher-servlet.xml中的组件扫描。假设ConfigBean类也使用@Component
或其中一个子类型进行注释,将创建两个实例。一次用于config.xml中的bean定义,一次用于组件扫描。
要解决此问题,您需要更改组件扫描以忽略非控制器类。
<context:component-scan user-default-filters='false'>
<context:include-filter annotation="org.springframework.stereotype.Controller"/>
</context:component-scan>
其他servlet类中的查找正在运行,因为您正在直接访问根应用程序上下文。
答案 2 :(得分:0)
这确实是相当愚蠢的。 <context:annotation-config />
指令应该在config.xml中,而不是dispatcher-servlet.xml。
据我了解,注释内容在父上下文中,因此指令所属的位置。