java - Spring Autowiring 服务在我的 Controller 中不起作用

标签 java spring spring-mvc

我在 Controller 中 Autowiring 服务时遇到了问题。我有这个错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private es.unican.meteo.service.UserService es.unican.meteo.controller.MyController.userService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [es.unican.meteo.service.UserService] 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)}

好像是userService没有注册,所以controller拿不到bean。我认为我的配置没问题,因为它适用于测试。在测试中我有这个:

ClassPathXmlApplicationContext("/WEB-INF/app-config.xml");

我可以从 ApplicationContext.xml 中获取 bean

我的包结构如下:

es.unican.meteo.controller

|---- MyController.java

es.unican.meteo.service

|---- 用户服务.java

es.unican.meteo.service.impl

|---- UserServiceImpl.java

.....

WebContent/WEB-INF

|---- MyDispatcherServlet-servlet.xml

|---- 应用配置.xml

|---- web.xml

.....

类:

== UserServiceImpl.java ==

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

== MyController.java ==

@Controller
public class MyController {

     @Autowired
     private UserService userService;

     @RequestMapping(method=RequestMethod.GET, value="/home")
     public String handleRequest(){
      return "welcome";
     }

     @RequestMapping(method=RequestMethod.GET, value="/getUsers")
     public @ResponseBody List<User> getUsersInJSON(){
      return userService.getUsers();
     }
}

== web.xml ==

<display-name>Spring MVC</display-name>

 <servlet>
  <servlet-name>MyDispatcherServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 </servlet>

 <servlet-mapping>
  <servlet-name>MyDispatcherServlet</servlet-name>
  <url-pattern>*.go</url-pattern>
 </servlet-mapping>
</web-app>

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


   <!-- Scans the classpath of this application for @Components to deploy as beans -->
   <context:component-scan base-package="es.unican.meteo" />

   <!-- Configures the @Controller programming model -->
   <mvc:annotation-driven/>

   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
    p:driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
    p:url="jdbc:derby:C:\tools\derbydb"
    p:connectionProperties=""
    p:username="APP"
    p:password="" />

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

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="/mybatis-config.xml" />
    </bean> 

    <bean id="usersMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="es.unican.meteo.dao.UserMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean> 

    <bean id="rolesMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="es.unican.meteo.dao.RoleMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean> 

</beans>

== MyDispatcherServlet.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: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.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

 <!-- Enabling Spring beans auto-discovery -->
 <context:component-scan base-package="es.unican.meteo.controller" />

 <!-- Enabling Spring MVC configuration through annotations -->
 <mvc:annotation-driven />

 <!-- Defining which view resolver to use -->
 <bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver" > 
  <property name="prefix" value="/WEB-INF/views/" /> 
  <property name="suffix" value=".jsp" /> 
 </bean>

Spring mvc 记录器跟踪:

19:38:54,119 DEBUG http-8080-1 support.DefaultListableBeanFactory:430 - Creating instance of bean 'myController'
19:38:54,170 DEBUG http-8080-1 annotation.InjectionMetadata:60 - Found injected element on class [es.unican.meteo.controller.MyController]: AutowiredFieldElement for private es.unican.meteo.service.UserService es.unican.meteo.controller.MyController.userService
19:38:54,174 DEBUG http-8080-1 support.DefaultListableBeanFactory:504 - Eagerly caching bean 'myController' to allow for resolving potential circular references
19:38:54,206 DEBUG http-8080-1 annotation.InjectionMetadata:85 - Processing injected method of bean 'myController': AutowiredFieldElement for private es.unican.meteo.service.UserService es.unican.meteo.controller.MyController.userService
19:38:54,224 DEBUG http-8080-1 support.DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'userServiceImpl'
19:38:54,226 DEBUG http-8080-1 support.DefaultListableBeanFactory:430 - Creating instance of bean 'userServiceImpl'
19:38:54,234 DEBUG http-8080-1 annotation.InjectionMetadata:60 - Found injected element on class [es.unican.meteo.service.impl.UserServiceImpl]: AutowiredFieldElement for private es.unican.meteo.dao.UserMapper es.unican.meteo.service.impl.UserServiceImpl.userMapper
19:38:54,237 DEBUG http-8080-1 support.DefaultListableBeanFactory:504 - Eagerly caching bean 'userServiceImpl' to allow for resolving potential circular references
19:38:54,256 DEBUG http-8080-1 annotation.InjectionMetadata:85 - Processing injected method of bean 'userServiceImpl': AutowiredFieldElement for private es.unican.meteo.dao.UserMapper es.unican.meteo.service.impl.UserServiceImpl.userMapper
19:38:54,268  INFO http-8080-1 support.DefaultListableBeanFactory:433 - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@56088b29: defining beans [myController,roleService,userServiceImpl,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.view.InternalResourceViewResolver#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
19:38:54,279 ERROR http-8080-1 servlet.DispatcherServlet:457 - Context initialization failed

我已经查看了有关此主题的一些问题,但没有找到解决问题的方法。也许我正在跳过一些东西,但我不确定。我尝试更改组件扫描但没有结果。

当我尝试访问/SPRING-MVC/getUsers.go 时出现这些错误。

我不知道 beans 是否必须放在 app-config (applicationContext) 或 servlet.xml 中,因为它有点令人困惑...

谢谢

最佳答案

你的配置很奇怪...

首先排除明显的

我在您的 web.xml 中没有看到根 Web 应用程序上下文配置.会不会是你忘了加这段代码?

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        WEB-INF/app-config.xml
    </param-value>
</context-param>

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

现在是一些理论

一些 Spring 理论 - Spring 使用 web 应用程序的应用程序上下文层次结构:

  • 顶级 Web 应用程序上下文由 ContextLoaderListener 加载
  • 然后每个 DispatcherServlet 都有单独的上下文实例

当一个新 bean 被实例化时,它可以从定义它的上下文或父上下文中获取依赖项。这使得在根上下文(服务、DAO 等)中定义公共(public) bean 并在 servlet 应用程序上下文中拥有请求处理 bean 成为可能,因为每个 servlet 都可以有自己的一组 Controller 、 View 处理程序、...

最后但并非最不重要的一点——你的错误

您正在根上下文中配置 MVC。那是错误的。删除 <mvc:那里的上下文。

您还通过 <context:component-scan> 在根上下文中注册您的 Controller 在你的基础包上。仅在 services 上进行组件扫描将您的类打包或分成两个顶级包 core (对于根 bean )和 servlet (对于 servlet bean)。

关于java - Spring Autowiring 服务在我的 Controller 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16894900/

相关文章:

java - spring security认证添加子域

java - 删除并添加回 JPanel 后,MouseEvent 不会在 JList 中触发

java - 使用 Spring 和 Apache Commons IO 的 Web 应用程序和目录观察器的线程问题

java - HttpClientErrorException getResponseBodyAsString() 无法将字节解析为字符串

spring - Grails Spring Security 静态规则

java - 使用 Spring 框架以原子方式维护服务层事务和数据库日志记录

java - 无法读取jsp中的bean属性

java - 找出网络上所有 Activity 机器的IP

java - 无法解析类型 org.apache.axiom.om.OMElement。它是从所需的 .class 文件间接引用的

java - 长轮询 10 秒后 Tomcat 7 服务器错误