zoukankan      html  css  js  c++  java
  • 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文件是否可以被正确扫描到,编译后的文件中是否存在以及路径是否正确

      

     

    <?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>
  • 相关阅读:
    自己用Django搭建的blog和用户权限
    python实现简单爬虫功能
    异步任务队列Celery在Django中的使用
    Django添加全文搜索功能入门篇
    Django 最好的缓存memcached的使用
    Django中添加富文本编辑器
    Python之Django 访问静态文件
    Django中url的逆向解析 -> Reverse resolution of URLs
    python(Django之html模板继承)
    IOS7以后无需自定义,改变UITabbarItem的图片文字颜色
  • 原文地址:https://www.cnblogs.com/mufengforward/p/11127088.html
Copyright © 2011-2022 走看看