簡體   English   中英

無法@Autowire Bean到控制器-NoSuchBeanDefinitionException

[英]Can't @Autowire a bean into a controller - NoSuchBeanDefinitionException

我有一個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>

dispatcher-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>

classpath: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;
    }
}

可能是因為您已將/WEB-INF/dispatcher-servlet.xml添加到context-param contextConfigLocation中。

不需要,因為Web應用程序上下文將根據Displater Servlet名稱准備文件。

春季文件

在初始化DispatcherServlet時,Spring MVC在Web應用程序的WEB-INF目錄中查找名為[servlet-name] -servlet.xml的文件,並創建在此定義的Bean,覆蓋所有用相同名稱定義的Bean的定義。在全球范圍內。

我認為由於存在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類中的查找有效。

事實證明這真是愚蠢。 <context:annotation-config />指令應該位於config.xml中,而不是位於dispatcher-servlet.xml中。

據我了解,注釋內容位於父上下文中,因此該指令屬於該內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM