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
一个数据类型的错误,浪费了一个多小时的时间。
总结心得:
遇到问题,不要着急。
分析问题。
确立解决问题的思路。
解决问题。
解决问题之后的总结。