ssm中mapper注入失败的传奇经历

最近因为要测试一个功能,需要用最短的时间来启动服务,开启测试程序,但平常所用的框架中已经集成了各种三方的东西,想着那就再重新搭建一个最简单的ssm框架吧。

搭建可参考:简单ssm最新搭建

 

搭建过程并不麻烦,整合springmvc测试成功,接口正常调用,最后整合mybatis后,在service中注入调用时出现了问题,启动服务时报错如下:

    No qualifying bean of type ‘com.test.mapper.TpmTestLogMapper‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

 

一、bug解决

 

首先先说一下我的错误原因:web.xml中没有配置监听器listener,也就是下边这些代码:


(其实配置了,但是不知道为什么最后发现是注释掉的,真的 头大!!!)

  <!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

(文末附有完整的web.xml配置,直接到文末

 

那么为什么没有配置监听,就导致mybatis注入失败了呢,这就不得不提到监听配置其中的一个作用了,监听加载容器配置文件,也就是Spring的配置文件applicationContext.xml。

 

加载流程:  tomcat服务启动时,会首先加载web.xml,然后监听器会默认去加载Spring的相关配置文件,从而创建spring容器中的各个bean组件。

 

默认加载的配置文件路径是:WEB-INF/applicationContext.xml,当然很多时候我们为了项目结构的清晰,会将此配置文件放在resource下,这时也需要在web.xml中额外配置

 

   <!--spring的其他配置文件(包括mybatis配置文件) -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:spring-applicationContext.xml
</param-value>
</context-param>

 

错误原因总结:启动文件web.xml中没有配置监听器,导致我的Spring相关配置文件没有加载,所以其中引入的spring-mybatis配置文件更不会加载,bean没有创建成功,最终导致了在service中调用时注入失败。

 

二、排查思路

 

排查过程中的思路:

  1. spring-mybatis整合配置文件路径是否正确,能否被扫描到

  2. mapper.java和mapper.xml之间有没有联系起来,数据库配置是否正确,mapper接口是否可以扫描到(查看配置文件)

  3. 有没有扫描到mapper.xml文件(查看编译文件,及对应路径是否正确)

 

1、检查spring-mybatis配置文件,在web.xml中是否可以扫描到:在serviceImpl中手动获取,看能否获取到

  @Override
  public void ceshi(TpmTestLog tpmTestLog) {
    //手动获取创建
  ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring-mybatis.xml");
  TpmTestLogMapper bean = ac.getBean(TpmTestLogMapper.class);
  bean.insert(tpmTestLog);
  System.out.println(bean.toString());
  }

测试是否可以成功获取到,可以,则表示mybatis路径正确,可以在web.xml中被正常扫描。

 

2、检查mybatis配置文件是否正确:主要是下方标红的两项配置会造成此错误

<!-- 读取配置文件信息 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties"/>

<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据库基本配置 -->
<property name="driverClassName" value="${jdbc.driver}" />
<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 name="maxActive" value="${jdbc.maxActive}"/>
<!-- 最小空闲连接数 -->
<property name="minIdle" value="${jdbc.minIdle}"/>
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${jdbc.maxWait}" />
<!-- 超过时间限制是否回收 -->
<property name="removeAbandoned" value="${jdbc.removeAbandoned}" />
<!-- 超过时间限制多长 -->
<property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
<!-- 用来检测连接是否有效的sql,要求是一个查询语句-->
<property name="validationQuery" value="${jdbc.validationQuery}" />
<!-- 申请连接的时候检测 -->
<property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
<!-- 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能 -->
<property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
<!-- 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能  -->
<property name="testOnReturn" value="${jdbc.testOnReturn}" />
<property name="logAbandoned" value="true" />
<!-- 配置监控统计拦截的filters,wall用于防止sql注入,stat用于统计分析 -->
<property name="filters" value="stat" />
</bean>

<!-- MyBatis SqlSessionFactoryBean 配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 自动扫描Mapping.xml文件 -->
<property name="mapperLocations" value="classpath:com/test/mapper/xml/*.xml"/>
<!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 扫描model包 xml中parameterType就可以使用类名,不用全路径 -->
<property name="typeAliasesPackage" value="com.test.model"/>
</bean>

<!-- 加载 mapper.xml对应的接口 配置文件 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 给出需要扫描mapper接口包 -->
<property name="basePackage" value="com.test.mapper"/>
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

 

3、mapper.xml文件是否可以被正确扫描到,编译后的文件中是否存在以及路径是否正确

   ssm中mapper注入失败的传奇经历

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
version="3.0">

<!--spring的其他配置文件(包括mybatis配置文件) -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:spring-applicationContext.xml
</param-value>
</context-param>

<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- Spring监听器 监听加载相关配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--防止Spring内存溢出监听器-->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

<!--Spring MVC servlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
<welcome-file>/index.html</welcome-file>
<welcome-file>/reg.html</welcome-file>
</welcome-file-list>
</web-app>

 

文章同步发布: https://www.geek-share.com/detail/2773149260.html

参考文章:

SSM中关于service中mapper注入失败org.springframework.beans.factory.UnsatisfiedDependencyException: Error crea

SSM框架---容器创建注入对象失败

ssm项目controller层@Value注解注入Integer等类型失败解决方法

mapper注入失败问题解决 {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Mybatis跳坑:Mapper注入单个基本类型参数失败There is no getter for property named

springMVC mybatis dao接口(mapper接口)注入失败

ssm中mapper注入失败的传奇经历

上一篇:Ubuntu启动器快捷方式文件解析app.desktop


下一篇:Android OkHttp + Retrofit 断点续传