zoukankan      html  css  js  c++  java
  • Spring读取配置文件无法解析问题

    问题背景:

    • 这个问题排查了有2-3天,尝试了各种组合配置没有解决。最后还是查资料看别人的解决经验解决了。

    问题现象:

    • 一个17年的老项目继续开发,其中是spring+mybatis+ibatis组合,基于一个更早12年的ibatis老项目开发的(开源otter)。把spring的配置datasource的xml文件中datasrouce的driver,url,username,password改成application.properties中使用spring的PropertyPlaceholderConfigurer来进行配置文件读取值替换。但是怎么配都提示变量无法解析。查了很多材料,都是说PropertyPlaceholderConfigurer的用法和spring怎么配外部配置文件的。没有关键信息、
    • 如果不用配置文件,直接写死是没问题的。使用xml中的properties属性也不行。
    • 错误如下图:
    • 怀疑与bean的初始化顺序有关,也就是datasource的bean初始化的时候还没有进行配置文件解析,PropertyPlaceholderConfigurer还没生效。

    主要探索过程:

    • 首先想到占位符的原理,参考该文章:
      • 深入Spring Boot:那些注入不了的Spring占位符(${}表达式)
      • https://blog.csdn.net/hengyunabc/article/details/75453307
      • 与该文章现象一致,并提示:结合上面的Spring的生命周期,如果Bean的创建和使用在PropertySourcesPlaceholderConfigurer之前,那么就有可能出现占位符没有被处理的情况。并提出:Mybatis 的 MapperScannerConfigurer引起的占位符没有处理,查出该类导致了datasource的bean提前初始化,在配置还没解析前。所以报错。
      • 大概原因就应该是这个。
    • 继续探索:
      • 从配置文件PropertySourcesPlaceholderConfigurer何时生效继续看,找出另一个文章:关于dubbo 占位符无法解析问题
      • https://blog.csdn.net/su20145104009/article/details/105160565
      • 该文提出思路:此时,只有一种想法,难道该 bean 的初始化早于 PropertySourcesPlaceholderConfigurer 的替换?也就是说,RegistryConfig 被提前初始化了
      • 该文提出解决方法:也关注到了:注册MapperScannerConfigurer的bean被提前初始化的问题
      • 但是改了其中的参数,还是没解决我的问题。但是排查问题过程更清晰。
    • 继续探索:
      • 在bing搜索:PropertyPlaceholderConfigurer无法注入,偶然得到一个文章:
      • PropertyPlaceholderConfigurer模式从properties加载数据源参数失败的解决方案
      • https://www.iteye.com/blog/yjy110-1882876
      • 报错类似,同时也将问题关注到了:一开始怀疑是spring版本问题,就搜索了一下“spring3 PropertyPlaceholderConfigurer”,结果发现还真有类似的提问,只不过比我问的更准确,一下就把问题定位到了问题的根源-------mybatis下的MapperScannerConfigurer扫描模式造成了bean的加载顺序改变从而使得PropertyPlaceholderConfigurer无法正常加载。
        改用sqlSessionFactoryBeanName注入就没有问题(不要使用sqlSessionFactory属性注入,使用sqlSessionFactoryBeanName注入),因为这时不会立即初始化sqlSessionFactory,传入的只是名字,非bean,所以不会引发提前初始化问题。。
      • 该文给出的MapperScannerConfigurer的sqlSessionFactory注入方式也没解决问题,不过已经可以确认问题就是这个。
      • 文中给出1个链接:https://www.oschina.net/question/188964_32305?sort=default&p=3
      • spring3.0.6 使用context:property-placeholder载不进属性
      • 该问题下面好多人遇到了类似问题,有人提出关键点:
      • 两种解决办法:
    1. <!-- mybatis文件配置,扫描所有mapper文件 -->
    <!-- configLocation为mybatis属性 mapperLocations为所有mapper -->
    <bean id="mb-sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" 
      p:dataSource-ref="dataSource" p:configLocation="classpath:web/sqlmap/mybatis-config.xml" 
      p:mapperLocations="classpath:web/sqlmap/mapper/*.xml" />
      <!-- spring与mybatis整合配置,扫描所有dao -->
      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"p:basePackage="com.jiezhibar.candy.web.dao" 
         p:sqlSessionFactoryBeanName="mb-sqlSessionFactory" />
      即:sqlSessionFactoryBeanName的值写成非sqlSessionFactory
    
    2、xml 头部将 default-autowire="byName"去掉
    
  • 相关阅读:
    N、Z、Q、R 分别代表什么
    Android常用代码-监听网络状态
    完整的android use SSL发送邮件
    android 发送邮件相关文章
    Spring RMI的实现原理
    spring+quartz配置
    Quartz配置表达式
    singleton容器
    Spring学习-框架概览
    [Shader2D]漩涡效果
  • 原文地址:https://www.cnblogs.com/drawnkid/p/15770953.html
Copyright © 2011-2022 走看看