Spring+MyBatis整合开发时 Injection of autowired dependencies failed的错误解决方法

Python转java开发,瞬间感觉框架好难受,总是不注意注解,找的很辛苦,读次文章,一定一定请注意注解,,,,,

今天在调试代码时,Spring启动后出现了错误:Injection of autowired dependencies failed;……的错误。

详细的错误信息如下:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed;
  • 1

经过一个多小时的Code Review和调试终于解决了问题,最后总结解决问题的方法,其实是MyBatis的一个映射文件中的resultType=”java.lang.Integer” parameterType=”java.lang.Integer”写错误。

但是这个错误却引发了Injection of autowired dependencies failed;……的错误。一开始以为是Spring配置文件错误了;再后来仔细检查各个包下面的注解;最后检查MyBatis配置文件时才发现了错误。

浪费时间的地方在于:一开始总是认为Spring配置文件和Spring注解使用错误;没有仔细检查MyBatis的映射文件。

在解决这个问题的过程中,在网上发现其实很多帖子,很多开发者都遇到过类似的问题;但是发现很多帖子都没有给出完整、准确的解决方法。所以总结一下解决过程和思路。

样例代码如下:

1. Spring配置文件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:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:util="http://www.springframework.org/schema/util"
    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.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、 
        PersistenceAnnotationBeanPostProcessor 以及 RequiredAnnotationBeanPostProcessor 
        这 4 个BeanPostProcessor。 注册这4个 BeanPostProcessor的作用,就是为了你的系统能够识别相应的注解。 -->
    <context:annotation-config />

    <!-- 在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的Java文件,如果扫描到有 @Component 
        @Controller@Service等这些注解的类,则把这些类注册为bean. 注意:如果配置了<context:component-scan> 
        那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者。 -->
    <context:component-scan base-package="com.keymen.*" />

    <bean
        class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.keymen.dao" />
        <property name="annotationClass" value="com.keymen.annotation.MyBatisDAO" />
    </bean>
    <!-- 在spring3以上版本中使用spring的依赖注入(注解或者xml方式)和aop功能时, 如果不设置<aop:aspectj-autoproxy 
        proxy-target-class="true"/> 那么在获取bean时一直报错(无论通过name还是type都获取不到bean) -->

    <!-- proxy-target-class="true" 与proxy-target-class="false"的区别: proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。 
        如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。 如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK基于接口的代理 -->

    <aop:aspectj-autoproxy proxy-target-class="true" />

    <!-- 加载jdbc连接时需要的properties属性文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" />

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="initialSize" value="${jdbc.initialSize}"></property>
        <property name="minIdle" value="${jdbc.minIdle}"></property>
        <property name="maxActive" value="${jdbc.maxActive}"></property>
        <property name="maxIdle" value="${jdbc.maxIdle}"></property>
        <property name="maxWait" value="${jdbc.maxWait}"></property>
    </bean>

    <!-- 配置dataSource -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 配置需要引用的mybatis.xml文件 -->
        <property name="configLocation" value="classpath:mybatis.xml"></property>
    </bean>

    <!-- 配置sqlSessionTemplate -->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"
        scope="prototype">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

    <!-- 配置事务管理方式 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

2. DAO层代码

package com.keymen.annotation;

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

@Repository
@Autowired
public @interface MyBatisDAO {


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
package com.keymen.dao;

import java.util.List;

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

import com.keymen.annotation.MyBatisDAO;
import com.keymen.entity.User;

@MyBatisDAO
public interface UserDao {

    @Autowired
    User selectByPrimaryKey(Integer id);
    @Autowired
    List<User> queryAllUser();
    @Autowired
    public User findUserByUsername(String username);
    @Autowired(required=true)
    public Integer getCountOfRecord();

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3. Service层代码

package com.keymen.service;

import java.util.List;
import java.util.Map;

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

import com.keymen.entity.User;

/**
 * 注意:这里的@Service注解不能少 
 */
@Service  
public interface UserService {

    @Autowired
    public User getUserById(int userId);
    @Autowired
    public List<User> queryAllUser();
    @Autowired
    public Map<String,User> findUserByUsername(String username);
    @Autowired
    public int getCountOfRecord();

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
package com.keymen.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import com.keymen.dao.UserDao;
import com.keymen.entity.User;
import com.keymen.service.UserService;

/**
 * 注意:这里的@Service注解不能少 
 */
@Service
@Transactional
public class UserServiceImpl implements UserService{

    @Autowired
    private UserDao userDao;

    @Override
    public User getUserById(int userId) {
        System.out.println("111---11111");
        System.out.println(userDao);
        return this.userDao.selectByPrimaryKey(userId);
    }

    @Override
    public List<User> queryAllUser() {
        // TODO Auto-generated method stub
        List<User> userList=this.userDao.queryAllUser();
        return userList;
    }

    @Override
    public Map<String,User> findUserByUsername(String username) {
        // TODO Auto-generated method stub
        User user=this.userDao.findUserByUsername(username);
        HashMap<String,User> userMap=new HashMap<String,User>();
        userMap.put(username, user);
        return userMap;
    }

    @Override
    public int getCountOfRecord() {
        // TODO Auto-generated method stub
        int count=this.userDao.getCountOfRecord();
        return count;
    }








}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

4. MyBatis映射文件代码

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.keymen.dao.UserDao">
    <resultMap id="BaseResultMap" type="com.keymen.entity.User">
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="userName" property="username" jdbcType="VARCHAR" />
        <result column="password" property="password" jdbcType="VARCHAR" />
        <result column="email" property="email" jdbcType="VARCHAR" />
        <result column="status" property="status" jdbcType="INTEGER" />
        <result column="createTime" property="createtime" jdbcType="TIMESTAMP" />
        <result column="udpateTime" property="udpatetime" jdbcType="TIMESTAMP" />
    </resultMap>

    <select id="selectByPrimaryKey" resultMap="BaseResultMap"
        parameterType="java.lang.Integer">
        select * from tb_user where id = #{id,jdbcType=INTEGER}
    </select>

    <select id="queryAllUser" resultMap="BaseResultMap"
        parameterType="java.util.List">
        select * from tb_user;
    </select>

    <select id="findUserByUsername" resultMap="BaseResultMap" parameterType="java.lang.String">
        select * from tb_user
        where username = #{username}
    </select>


    <select id="getCountOfRecord" resultType="java.lang.Integer" parameterType="java.lang.Integer">
        select count(*) from tb_user
    </select>


</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

5. 调试代码

package com.keymen.test;

import java.util.Map;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.keymen.entity.User;
import com.keymen.service.impl.UserServiceImpl;

public class TestGetCountOfRecord {

    public static ApplicationContext ctx=null;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("Hello Spring MyBatis!");
        System.out.println("Count of Records:");
        ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserServiceImpl userServiceImpl = (UserServiceImpl) ctx.getBean("userServiceImpl");


        int countOfRecord = userServiceImpl.getCountOfRecord();
        System.out.println("Total Count of Records: "+countOfRecord);

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

出错的代码:

<select id="getCountOfRecord" resultType="java.lang.int" parameterType="java.lang.int">
        select count(*) from tb_user
    </select>
  • 1
  • 2
  • 3

修改之后的代码:

<select id="getCountOfRecord" resultType="java.lang.Integer" parameterType="java.lang.Integer">
        select count(*) from tb_user
    </select>
  • 1
  • 2
  • 3

一个数据类型的错误,浪费了一个多小时的时间。

总结心得:

遇到问题,不要着急。 
分析问题。 
确立解决问题的思路。 
解决问题。 
解决问题之后的总结。

猜你喜欢

转载自blog.csdn.net/Com_ma/article/details/81195300