Mybatis+Spring整合问题,NoSuchBeanDefinitionException

  • junit测试上出了问题如下:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:252)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private occ.myframework.dao.UserInfoMapper occ.myframework.service.impl.UserServiceImpl.userInfoMapper; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [occ.myframework.dao.UserInfoMapper] 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)}
Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userInfoMapper' defined in file [/Users/fanwei/IdeaProjects/Springmybatis/target/classes/occ/myframework/dao/UserInfoMapper.class]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-mybatis.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.core.io.Resource[]' for property 'mapperLocations'; nested exception is java.lang.IllegalArgumentException: Could not resolve resource location pattern [classpath:occ/myframework/mapping/*.xml]: class path resource [occ/myframework/mapping/] cannot be resolved to URL because it does not exist
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    ... 28 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private occ.myframework.dao.UserInfoMapper occ.myframework.service.impl.UserServiceImpl.userInfoMapper; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [occ.myframework.dao.UserInfoMapper] 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$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 44 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [occ.myframework.dao.UserInfoMapper] 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.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 46 more
  • 测试代码如下:

import occ.myframework.model.UserInfo;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml",
        "classpath:spring-mybatis.xml"})
public class UserServiceTest {

    private static final Logger LOGGER = Logger
            .getLogger(UserServiceTest.class);

    @Autowired
    private UserService userService;

    @Test
    public void testGetUserById() throws Exception {
        UserInfo userInfo = userService.getUserById(1);
        System.out.println(userInfo);
    }
}
  • 代码如下:
    dao层

public interface UserInfoMapper {

    UserInfo selectByPrimaryKey(Integer id);

    List<UserInfo> selectAll();
}
service层
public interface UserService {

    UserInfo getUserById(int id);

    List<UserInfo> getUsers();
}
service层下的实现类:
@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public UserInfo getUserById(int id) {
        return userInfoMapper.selectByPrimaryKey(new Integer(id));
    }

    @Override
    public List<UserInfo> getUsers() {
        return userInfoMapper.selectAll();
    }
}

mapping配置文件:UserInfoMapper.xml

<?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="occ.myframework.dao.UserInfoMapper">
    <resultMap id="userInfo" type="occ.myframework.model.UserInfo">
        <id property="id" column="id" jdbcType="INTEGER" />
        <result property="uname" column="uname" jdbcType="VARCHAR" />
        <result property="unumber" column="unumber" jdbcType="INTEGER" />
    </resultMap>
    <!-- 一对多映射 -->
    <resultMap id="UserCourseMap" type="occ.myframework.model.UserInfo" extends="userInfo">
        <collection property="courseInfos" javaType="list" ofType="occ.myframework.model.CourseInfo">
            <id property="id" column="cousrse_id" jdbcType="INTEGER" />
            <result property="cname" column="cname" jdbcType="VARCHAR" />
            <result property="caddress" column="caddress" jdbcType="VARCHAR" />
        </collection>
    </resultMap>

    <sql id="Base_Column_List">
        id,uname,unumber
    </sql>

    <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="userInfo" >
        SELECT
        <include refid="Base_Column_List"/>
        FROM user_info WHERE id=#{id}
    </select>

    <select id="selectAll" resultType="UserCourseMap">
        SELECT u.*,c.id AS cousrse_id,c.caddress,c.cname
        FROM user_info u LEFT JOIN course_user_info cu
        ON u.id=cu.uid
        LEFT JOIN course_info c
        ON c.id=cu.cid
    </select>
</mapper>
spring.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd">
       <!--引入配置属性文件 -->
       <context:property-placeholder location="classpath:config.properties" />

       <!--自动扫描含有@Service将其注入为bean -->
       <context:component-scan base-package="occ.myframework.service" />
</beans>
spring-mybatis.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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

       <!-- 配置数据源 使用的是Druid数据源 -->
       <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
              <property name="url" value="${jdbc.url}" />
              <property name="username" value="${jdbc.username}" />
              <property name="password" value="${jdbc.password}" />
              <!-- 初始化连接大小 -->
              <property name="initialSize" value="0" />
              <!-- 连接池最大使用连接数量 -->
              <property name="maxActive" value="20" />

              <!-- 连接池最小空闲 -->
              <property name="minIdle" value="0" />
              <!-- 获取连接最大等待时间 -->
              <property name="maxWait" value="60000" />
              <property name="poolPreparedStatements" value="true" />
              <property name="maxPoolPreparedStatementPerConnectionSize"
                        value="33" />
              <!-- 用来检测有效sql -->
              <property name="validationQuery" value="${validationQuery}" />
              <property name="testOnBorrow" value="false" />
              <property name="testOnReturn" value="false" />
              <property name="testWhileIdle" value="true" />
              <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
              <property name="timeBetweenEvictionRunsMillis" value="60000" />
              <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
              <property name="minEvictableIdleTimeMillis" value="25200000" />
              <!-- 打开removeAbandoned功能 -->
              <property name="removeAbandoned" value="true" />
              <!-- 1800秒,也就是30分钟 -->
              <property name="removeAbandonedTimeout" value="1800" />
              <!-- 关闭abanded连接时输出错误日志 -->
              <property name="logAbandoned" value="true" />
              <!-- 监控数据库 -->
              <property name="filters" value="mergeStat" />
       </bean>

       <!-- myBatis-spring配置文件 -->
       <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource" />
              <!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 -->
              <property name="mapperLocations" value="classpath:occ/myframework/mapping/*.xml" />
       </bean>

       <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
              <property name="basePackage" value="occ.myframework.dao" />
       </bean>

       <!-- 配置事务管理器 -->
       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource" />
       </bean>

       <!-- 注解方式配置事物 -->
       <!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->

       <!-- 拦截器方式配置事物 -->
       <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
              <tx:attributes>
                     <tx:method name="insert*" propagation="REQUIRED" />
                     <tx:method name="update*" propagation="REQUIRED" />
                     <tx:method name="delete*" propagation="REQUIRED" />

                     <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
                     <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
                     <tx:method name="select*" propagation="SUPPORTS" read-only="true" />

              </tx:attributes>
       </tx:advice>
       <!-- Spring aop事务管理 -->
       <aop:config>
             <aop:pointcut id="transactionPointcut" expression="execution(* occ.myframework.service..*Impl.*(..))" />
             <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
       </aop:config>
</beans>
阅读 13.4k
2 个回答

答案我你已经修改了
主要原因有两个:

  1. 编译classes文件后,mapper.xml压根没有,所以SQLsessionfactory不能读取成功,这里需要在maven上配置这个:

<resources>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
          <include>**/*.tld</include>
        </includes>
        <filtering>false</filtering>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
          <include>**/*.tld</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  1. sping自动扫描不到需要的包下的类接口:

       spring.xml修改如下:
    
<!--自动扫描含有@Service将其注入为bean -->
       <context:component-scan base-package="occ.myframework" />

仔细看下异常:
Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.core.io.Resource[]' for property 'mapperLocations'; nested exception is java.lang.IllegalArgumentException: Could not resolve resource location pattern [classpath:occ/myframework/mapping/*.xml]: class path resource [occ/myframework/mapping/] cannot be resolved to URL because it does not exist
检查下路径,配置文件没有找到

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏