【问题标题】:Error when spring-servlet.xml tries to autowire beans defined in application-context.xmlspring-servlet.xml 尝试自动装配 application-context.xml 中定义的 bean 时出错
【发布时间】:2015-09-16 14:14:53
【问题描述】:

所以我正在尝试使用 Spring 创建一个 Rest Web 服务,该服务将具有通过 MyBatis 接口联系我的数据库的控制器。我的 Service 和 Repository bean 在 application-context.xml 中自动装配,我的控制器在 spring-servlet.xml 中注入。我的问题是,当我尝试在本地 tomcat 服务器上部署我的战争时,我收到以下错误;

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teamController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.programme.server.service.TeamService com.programme.server.controller.TeamController.teamService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.programme.server.service.TeamService] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:629)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:677)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:548)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1231)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1144)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1031)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4914)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5201)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.programme.server.service.TeamService com.programme.server.controller.TeamController.teamService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.programme.server.service.TeamService] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 29 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.programme.server.service.TeamService] 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)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1261)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1009)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)

应用程序上下文.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                    http://www.springframework.org/schema/context 
                    http://www.springframework.org/schema/context/spring-context-4.0.xsd
                    http://www.springframework.org/schema/tx 
                    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<context:component-scan base-package="com.programme.server">
    <context:exclude-filter type="regex" 
                   expression="com.programme.server.controller.*Controller.*" />
</context:component-scan>

<tx:annotation-driven transaction-manager="transactionManager"/>

<context:property-placeholder location="jdbc.properties"/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName"> 
        <value>${jdbc.driverClassName}</value> 
    </property> 
    <property name="url"> 
        <value>${jdbc.url}</value> 
    </property> 
    <property name="username"> 
        <value>${jdbc.username}</value> 
    </property> 
    <property name="password"> 
        <value>${jdbc.password}</value> 
    </property> 
</bean> 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="typeAliasesPackage" value="com.programme.server.domain" />
  <property name="mapperLocations" value="classpath*:/resources/mappers/*.xml" />
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.programme.server.mapper" />
</bean>
</beans>

spring-servlet.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <context:component-scan base-package="com.programme.server.controller" />

    <mvc:default-servlet-handler/>

    <mvc:annotation-driven />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>



</beans>

web.xml:

  <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>Programme Application</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:application-context.xml
         </param-value> 
     </context-param>

    <listener>
       <listener-class>
            org.springframework.web.context.ContextLoaderListener
       </listener-class>
    </listener> 

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

控制器抛出错误...

import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.programme.server.domain.Team;
import com.programme.server.service.TeamService;

@RestController
@RequestMapping("/team")
public class TeamController {

    @Autowired
    private TeamService teamService;

    @RequestMapping(method=RequestMethod.GET)
    public @ResponseBody Team retrieveTeam(@PathVariable("id") int id){
        return teamService.retrieveTeam(id);
    }
}

这是服务实现...

package com.programme.server.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.programme.server.dao.TeamDao;
import com.programme.server.domain.Team;

@Service
public final class TeamServiceImpl implements TeamService {

    @Autowired
    private TeamDao teamDao;

    @Override
    public List<Team> finalAll() {
        return teamDao.findAll();
    }

    @Override
    public Team retrieveTeam(int id) {
        return teamDao.retrieveTeam(id);
    }

}

和界面...

package com.programme.server.service;

import java.util.List;

import com.programme.server.domain.Team;

public interface TeamService {

    public List<Team> finalAll();

    public Team retrieveTeam(int id);
}

Service 层肯定有“@Service”注解,我已经用“main”应用程序进行了测试,并且每次都被注入 - 这让我相信问题出在 spring-servlet.xml 不知道 bean由“application-context.xml”注入。我很困惑为什么这会是一个问题,但是因为我认为 application-context.xml 充当了 servlet 上下文的“父”上下文。关于这里出了什么问题的任何帮助都会很棒。我需要在应用程序上下文中注入所有内容吗?我还提供了我的项目层次结构的屏幕截图...

【问题讨论】:

  • 对于初学者来说,清理你的配置。从application-context.xml 中删除&lt;mvc:/&gt; 内容,将&lt;mvc:default-servlet-handler/&gt; 添加到spring-servlet.xml。还要从spring-servlet.xml 中删除&lt;tx:annotation-driven /&gt;。此外,您正在扫描所有与 Web 相关的 bean 两次,将排除过滤器添加到您的 application-context.xml 中的 component-scan。请添加服务代码。
  • @M.Deinum- 感谢您的帮助。所以我做了你上面提到的改变,但仍然没有改变:/有没有办法专门告诉 spring-servlet.xml 关于 application-context.xml bean?我打算使用 但这对我来说似乎不合适
  • 不,因为它们被用作父母。如果找不到它们,则不会实例化。查看您的 web.xml,您没有任何内容加载您的 application-context.xml... 没有 ContextLoaderListener 所以首先不会加载任何内容。
  • 好吧,至少我的理解是正确的 :) 你是对的,但我忘了将 ContextLoaderListener 类添加到 web.xml - 我假设这就是你上面提到的?我添加了这个,我的 Tomcat 现在可以正常启动了,谢谢

标签: java spring rest spring-mvc mybatis


【解决方案1】:

所以只是为了关闭它......

对我来说解决方法是添加

<listener>
   <listener-class>
        org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener> 

到我的 web.xml。我在这里有 applicatiopn-context.xml 的上下文路径,但我想我实际上并没有在启动时加载它,因此没有注入任何 bean

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多