【问题标题】:Spring-mybatis connection fails with UnsatisfiedDependencyExceptionSpring-mybatis 连接失败,出现 UnsatisfiedDependencyException
【发布时间】:2019-05-03 22:34:22
【问题描述】:

我对 Spring 比较陌生,在建立 spring-mybatis 设置环境时遇到了问题。这是我的代码。我得到的例外是

org.springframework.beans.factory.UnsatisfiedDependencyException:为 com.infosender.service.UserServiceImpl 创建名为“loginController”的 bean 时出错。

我不明白这个问题。因为 UserServiceImpl 对象是在 LoginController 中自动装配的,而 UserServiceImpl 类是自动装配到 UserDaoMapper 接口的,所以应该有一个名为 UserServiceImpl 的 bean。为什么找不到 bean 的原因?

package com.infosender.controller;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.infosender.user.User;
import com.infosender.user.UserDao;
import com.infosender.user.UserDaoMapper;
import com.infosender.service.UserService;
import com.infosender.service.UserServiceImpl;;


@Controller
public class LoginController {

    //UserService userService = UserService.getInstance();
    @Autowired
    UserServiceImpl userServiceImpl;

    @RequestMapping(value="/login", method=RequestMethod.POST)
    public String handleRequestInternal(
            @ModelAttribute("username") String user_id,
            @ModelAttribute("password") String user_pw
            ) {
        User user = null;
        try {
            user = userServiceImpl.getUserByIdAndPw(user_id, user_pw);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if(user == null) {
            return "login_fail";
        }
        return "main_menu";     
    }
}

这里是 UserService 和 UserServiceImpl

package com.infosender.service;

import java.sql.SQLException;    
import javax.inject.Inject;    
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;    
import com.infosender.user.User;
import com.infosender.user.UserDao;    
public interface UserService {

    public User getUserByIdAndPw(String user_id, String user_pw)throws SQLException;
}

package com.infosender.service;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import com.infosender.user.User;
import com.infosender.user.UserDao;
import com.infosender.user.UserDaoMapper;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDaoMapper userDaoMapper;    

    public User getUserByIdAndPw(String user_id, String user_pw)throws SQLException {
        return userDaoMapper.getUserByIdAndPw(user_id, user_pw);
    }   
}

这里有 UserDao 和 UserDaoMapper

package com.infosender.user;

import java.sql.SQLException;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;

@Repository
public class UserDao implements UserDaoMapper{

    @Autowired  
    private SqlSessionTemplate sqlSession;


    public void setSqlSessionTemplate(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    public User getUserByIdAndPw(String user_id, String user_password) {
        UserDaoMapper mapper = sqlSession.getMapper(UserDaoMapper.class);
        return mapper.getUserByIdAndPw(user_id, user_password);

        //return sqlSession.selectOne("com.infosender.user.UserDaoMapper.getUserByIdAndPw");        
    }   
}

package com.infosender.user;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

public interface UserDaoMapper {
    public User getUserByIdAndPw(@Param("user_id")String user_id,@Param("user_password")String user_password);  
}

下面是root-context.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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
        http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.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-3.2.xsd">

    <context:annotation-config/>



    <!-- org.apache.commons.dbcp.BasicDataSource -->
    <!-- Root Context: defines shared resources visible to all other web components -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/InfoSender"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:/WEB_INF/spring/mybatis/mybatis-config.xml"></property>
        <property name="mapperLocations" value="classpath:*/mappers/*mapper.xml"></property>
    </bean>

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
    </bean>

<!--    <bean id="userDaoMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.infosender.user.UserDaoMapper"></property>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>

    </bean>
     -->

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

    </beans>

这是整个错误日志

ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.infosender.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1378)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:696)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:662)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:710)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:587)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:526)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:169)
    at javax.servlet.GenericServlet.init(GenericServlet.java:158)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1238)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1151)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1038)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5027)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5337)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.infosender.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1646)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1205)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1166)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
    ... 31 more

【问题讨论】:

  • 请注意,您应该使用接口而不是具体实现,在这种情况下,请在代码中更改为@Autowired UserService userService;
  • 感谢@LipingHuang,但即使修复了这个问题,它仍然会因为没有名为“用户服务”的bean而失败..
  • 那么您需要注册您的自定义用户详细信息服务并使用 spring @Bean 注释进行注释。
  • @LipingHuang 但是我没有使用 bean 注册 UserServiceImpl bean,而是使用 Service 注释来创建这样的 bean。它不应该工作吗..?
  • 你能发布整个堆栈跟踪吗?

标签: spring spring-mvc mybatis


【解决方案1】:

致任何可能查看此页面的人。

问题实际上出在我的 web.xml 文件中。在那里我声明了两个带有 contextConfigLocation 标签的 xml 文件:root-context.xml 和 mybatis-config.xml。 我所做的是我“单独”编写它们,因此(我认为)后者以某种方式覆盖了前者,而不是按照应有的方式创建 sqlSession bean。

正如 cmets 所建议的,代码中存在一些错误。但这是未创建 bean 的主要原因。

【讨论】:

    猜你喜欢
    • 2019-04-01
    • 2014-07-04
    • 2011-12-31
    • 2017-11-14
    • 1970-01-01
    • 2012-05-04
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多