spring mvc @Autowired error Unsatisfied 'required' dependency of type

旧城冷巷雨未停 提交于 2019-12-08 09:56:53

问题


I have user service that treat user entity, and @Autowired in user controller class before use user service. 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

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)

@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

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

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

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

<?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.

What is the problem cause the error?

Answer: The problem was what was described in Sotirios Delimanolis answer. The Exact solution described in comments on his answer

thank you


回答1:


Your application context and servlet context are component scanning over the same packages.

Your application context

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

Versus everything in servlet context

<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. You don't want this. Your servlet context should scan for @Controller beans. 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.



来源:https://stackoverflow.com/questions/18473236/spring-mvc-autowired-error-unsatisfied-required-dependency-of-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!