简体   繁体   English

spring mvc @Autowired错误类型的不满足“必需”依赖性

[英]spring mvc @Autowired error Unsatisfied 'required' dependency of type

I have user service that treat user entity, and @Autowired in user controller class before use user service. 我有处理用户实体的用户服务,并且在使用用户服务之前在用户控制器类中使用@Autowired。 so, I got the error: 所以,我得到了错误:

Unsatisfied 'required' dependency of type [class com.yes.service.UserService]. Expected at least 1 matching bean

here the codes: 这里的代码:

userService userService

package com.yes.service;

import java.util.List;
import java.util.UUID;

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

import com.yes.domain.User;
import com.yes.repository.RoleRepository;
import com.yes.repository.UserRepository;

@Service
public class UserService {


    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;

    public User create(User user) {
        user.setId(UUID.randomUUID().toString());
        user.getRole().setId(UUID.randomUUID().toString());
        // We must save both separately since there is no cascading feature
        // in Spring Data MongoDB (for now)
        roleRepository.save(user.getRole());
        return userRepository.save(user);
    }
    public User read(User user) {
        return user;
    }
    public List<User> readAll() {
        return userRepository.findAll();
    }
    public User update(User user) {
        User existingUser = userRepository.findByUsername(user.getUserName());
        if (existingUser == null) {
            return null;
        }
        existingUser.setFirstName(user.getFirstName());
        existingUser.setLastName(user.getLastName());
        existingUser.getRole().setRole(user.getRole().getRole());
        // We must save both separately since there is no cascading feature
        // in Spring Data MongoDB (for now)
        roleRepository.save(existingUser.getRole());
        return userRepository.save(existingUser);
    }
    public Boolean delete(User user) {
        User existingUser = userRepository.findByUsername(user.getUserName());
        if (existingUser == null) {
            return false;
        }
        // We must delete both separately since there is no cascading feature
        // in Spring Data MongoDB (for now)
        roleRepository.delete(existingUser.getRole());
        userRepository.delete(existingUser);
        return true;
    }
}

userController (where i use the userService, and the problem is) userController(我使用userService的地方,问题是)

@Controller
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService service;
    @RequestMapping
    public String getUsersPage() {
        return "users";
    }
    @RequestMapping(value="/records")
    public @ResponseBody UserListDto getUsers() {
        UserListDto userListDto = new UserListDto();
        userListDto.setUsers(service.readAll());
        return userListDto;
    }
    @RequestMapping(value="/get")
    public @ResponseBody User get(@RequestBody User user) {
        return service.read(user);
    }

    @RequestMapping(value="/create", method=RequestMethod.POST)
    public @ResponseBody User create(
            @RequestParam String username,
            @RequestParam String password,
            @RequestParam String firstName,
            @RequestParam String lastName,
            @RequestParam Integer role) {

        Role newRole = new Role();
        newRole.setRole(role);
        User newUser = new User();
        newUser.setUserName(username);
        newUser.setPassword(password);
        newUser.setFirstName(firstName);
        newUser.setLastName(lastName);
        newUser.setRole(newRole);
        return service.create(newUser);
    }
    @RequestMapping(value="/update", method=RequestMethod.POST)
    public @ResponseBody User update(
            @RequestParam String username,
            @RequestParam String firstName,
            @RequestParam String lastName,
            @RequestParam Integer role) {

        Role existingRole = new Role();
        existingRole.setRole(role);
        User existingUser = new User();
        existingUser.setUserName(username);
        existingUser.setFirstName(firstName);
        existingUser.setLastName(lastName);
        existingUser.setRole(existingRole);
        return service.update(existingUser);
    }
    @RequestMapping(value="/delete", method=RequestMethod.POST)
    public @ResponseBody Boolean delete(
            @RequestParam String username) {

        User existingUser = new User();
        existingUser.setUserName(username);
        return service.delete(existingUser);
    }
}

spring-data.xml 弹簧data.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:c="http://www.springframework.org/schema/c" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-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/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd">

    <context:property-placeholder
        properties-ref="deployProperties" />


    <!-- MongoDB host -->
    <mongo:mongo host="${mongo.host.name}" port="${mongo.host.port}" />

    <!-- Template for performing MongoDB operations -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"
        c:mongo-ref="mongo" c:databaseName="${mongo.db.name}" />

    <!-- Activate Spring Data MongoDB repository support -->
    <mongo:repositories base-package="com.yes.repository" mongo-template-ref="mongoTemplate"/>



    <!-- Service for initializing MongoDB with sample data using MongoTemplate -->
    <bean id="initMongoService" class="com.yes.service.InitMongoService" init-method="init"/>
</beans>

servlet-context.xml servlet的context.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    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">

<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<context:component-scan base-package="com.yes.controller"/>



<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

applicationContext.xml applicationContext.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.xsd">
<context:property-placeholder
    properties-ref="deployProperties" />

<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />

<!-- Scans the classpath for annotated components that will be auto-registered 
    as Spring beans. For example @Controller and @Service. Make sure to set the 
    correct base-package -->

    <context:component-scan base-package="com.yes.domain"/>
    <context:component-scan base-package="com.yes.dto"/>
    <context:component-scan base-package="com.yes.service"/>

<!-- Configures the annotation-driven Spring MVC Controller programming 
    model. Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />

<!-- Imports datasource configuration -->
<import resource="spring-data.xml" />
<bean id="deployProperties"
    class="org.springframework.beans.factory.config.PropertiesFactoryBean"
    p:location="/WEB-INF/spring/spring.properties" />

the error stack: 错误堆栈:

ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.yes.service.UserService com.yes.controller.UserController.service; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.yes.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)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)

web.xml web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/applicationContext.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

EDIT: the question is after fix the errors written in Sotirios Delimanolis answer and comment. 编辑:问题是在解决Sotirios Delimanolis回答和评论中所写的错误之后。

What is the problem cause the error? 是什么原因导致错误?

Answer: The problem was what was described in Sotirios Delimanolis answer. 答:问题是Sotirios Delimanolis答案中描述的问题。 The Exact solution described in comments on his answer 确切的解决方案在他的回答评论中描述

thank you 谢谢

Your application context and servlet context are component scanning over the same packages. 您的应用程序上下文和Servlet上下文是对相同程序包的组件扫描。

Your application context 您的应用程序上下文

<context:component-scan base-package="com.yes" />

Versus everything in servlet context 与Servlet上下文中的所有内容

<context:component-scan base-package="com.yes.service"/>
<context:component-scan base-package="com.yes.controller"/>
<context:component-scan base-package="com.yes.domain"/>
<context:component-scan base-package="com.yes.repository"/>
<context:component-scan base-package="com.yes.dto"/>

So some beans will be overriden. 因此,一些bean将被覆盖。 You don't want this. 你不要这个 Your servlet context should scan for @Controller beans. 您的Servlet上下文应扫描@Controller bean。 Your application context should scan for everything else, but don't make your application context scan for things already scanned by your child (imported) data context. 您的应用程序上下文应该扫描其他所有内容,但是不要让您的应用程序上下文扫描您的孩子(导入的)数据上下文已经扫描的内容。 Fix your package declarations so all of these are disjoint. 修正您的包裹声明,使所有这些声明不相交。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM