为什么80%的码农都做不了架构师?>>>   

package com.myapp.util;import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.NestedIOException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;/*** mapper.xml热加载,修改mapper.xml不需要重启tomcat,正式环境需要去掉*/
@Service
public class XMLMapperLoader implements DisposableBean, InitializingBean, ApplicationContextAware {private ConfigurableApplicationContext context = null;private transient String basePackage = null;private HashMap<String, String> fileMapping = new HashMap<String, String>();private Scanner scanner = null;private ScheduledExecutorService service = null;public void setApplicationContext(ApplicationContext applicationContext) {this.context = (ConfigurableApplicationContext) applicationContext;}public void afterPropertiesSet() throws Exception {try {service = Executors.newScheduledThreadPool(1);// 获取xml所在包MapperScannerConfigurer config = context.getBean(MapperScannerConfigurer.class);Field field = config.getClass().getDeclaredField("basePackage");field.setAccessible(true);basePackage = (String) field.get(config);// 触发文件监听事件scanner = new Scanner();scanner.scan();service.scheduleAtFixedRate(new Task(), 5, 5, TimeUnit.SECONDS);} catch (Exception e1) {e1.printStackTrace();}}class Task implements Runnable {public void run() {try {if (scanner.isChanged()) {System.out.println("*Mapper.xml文件改变,重新加载.");scanner.reloadXML();System.out.println("加载完毕.");}} catch (Exception e) {e.printStackTrace();}}}@SuppressWarnings({ "rawtypes" })class Scanner {private String[] basePackages;private static final String XML_RESOURCE_PATTERN = "**/*.xml";private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();public Scanner() {basePackages = StringUtils.tokenizeToStringArray(XMLMapperLoader.this.basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);}public Resource[] getResource(String basePackage, String pattern) throws IOException {String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+ ClassUtils.convertClassNameToResourcePath(context.getEnvironment().resolveRequiredPlaceholders(basePackage)) + "/" + pattern;Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);return resources;}public void reloadXML() throws Exception {SqlSessionFactory factory = context.getBean(SqlSessionFactory.class);Configuration configuration = factory.getConfiguration();// 移除加载项removeConfig(configuration);// 重新扫描加载for (String basePackage : basePackages) {Resource[] resources = getResource(basePackage, XML_RESOURCE_PATTERN);if (resources != null) {for (int i = 0; i < resources.length; i++) {if (resources[i] == null) {continue;}try {XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(resources[i].getInputStream(),configuration, resources[i].toString(), configuration.getSqlFragments());xmlMapperBuilder.parse();} catch (Exception e) {throw new NestedIOException("Failed to parse mapping resource: '" + resources[i] + "'", e);} finally {ErrorContext.instance().reset();}}}}}private void removeConfig(Configuration configuration) throws Exception {Class<?> classConfig = configuration.getClass();clearMap(classConfig, configuration, "mappedStatements");clearMap(classConfig, configuration, "caches");clearMap(classConfig, configuration, "resultMaps");clearMap(classConfig, configuration, "parameterMaps");clearMap(classConfig, configuration, "keyGenerators");clearMap(classConfig, configuration, "sqlFragments");clearSet(classConfig, configuration, "loadedResources");}private void clearMap(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {Field field = classConfig.getDeclaredField(fieldName);field.setAccessible(true);Map mapConfig = (Map) field.get(configuration);mapConfig.clear();}private void clearSet(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {Field field = classConfig.getDeclaredField(fieldName);field.setAccessible(true);Set setConfig = (Set) field.get(configuration);setConfig.clear();}public void scan() throws IOException {if (!fileMapping.isEmpty()) {return;}for (String basePackage : basePackages) {Resource[] resources = getResource(basePackage, XML_RESOURCE_PATTERN);if (resources != null) {for (int i = 0; i < resources.length; i++) {String multi_key = getValue(resources[i]);fileMapping.put(resources[i].getFilename(), multi_key);}}}}private String getValue(Resource resource) throws IOException {String contentLength = String.valueOf((resource.contentLength()));String lastModified = String.valueOf((resource.lastModified()));return new StringBuilder(contentLength).append(lastModified).toString();}public boolean isChanged() throws IOException {boolean isChanged = false;for (String basePackage : basePackages) {Resource[] resources = getResource(basePackage, XML_RESOURCE_PATTERN);if (resources != null) {for (int i = 0; i < resources.length; i++) {String name = resources[i].getFilename();String value = fileMapping.get(name);String multi_key = getValue(resources[i]);if (!multi_key.equals(value)) {isChanged = true;fileMapping.put(name, multi_key);}}}}return isChanged;}}public void destroy() throws Exception {if (service != null) {service.shutdownNow();}}}

转载于:https://my.oschina.net/houke/blog/282445

Spring实现热加载MyBatis 的XML配置文件相关推荐

  1. 综合案例:使用Configmap-reload动态热加载Configmap中的配置文件(三十七)

    综合案例:使用Configmap-reload动态热加载Configmap中的配置文件 文章目录 综合案例:使用Configmap-reload动态热加载Configmap中的配置文件 1.confi ...

  2. 利用SPRING管理热加载的GROOVY对象!

    作者:paleXu的技术博客 来源:https://palexu.github.io/posts/spring-dynamic-load-groovy-bean?hmsr=toutiao.io& ...

  3. tomcat热加载、热部署-源码解析

    上文:tomcat线程模型-源码解析 热加载和热部署是什么? 请查看原来的写过的文章:热部署和热加载有什么区别? tomcat热加载和执热部署都是通过后台进程检测项目中的.class和目录是否发生变化 ...

  4. springboot mybatis 热加载mapper.xml文件(最简单)

    大家好,我是烤鸭: 今天介绍一下springboot mybatis 热加载mapper.xml文件. 本来不打算写的,看到网上比较流行的方式都比较麻烦,想着简化一下. 网上流行的版本. https: ...

  5. mybatis热加载的实现

    最近在使用mybatis,由于是刚刚开始用,用的并不顺手,目前是感觉有2个地方非常的不好用: 1.mybatis调试不方便 由于dao层只有接口,实现只是一个map的xml文件,想加断点都没有地方加, ...

  6. spring boot:从零开始搭建一个项目 - day 7 springboot devtools热加载+MybatisPlus配置+kisso从入门到放弃

    spring boot:从零开始搭建一个项目 - day 7 springboot devtools热加载+MybatisPlus配置+kisso从入门到放弃 一.springboot devtool ...

  7. Nacos Spring Cloud 实现配置热加载

    0x01:安装 Nacos 下载安装包, https://github.com/alibaba/nacos/releases 从下载 nacos-server-$version.zip 安装包. 解压 ...

  8. Spring Boot + IntelliJ IDEA——自动部署[Spring Boot热部署]+LiveReload[前端自动刷新、热加载]解决方案

    基本概念 spring-boot-devtools: Spring Boot包括一组额外的工具,这些工具可以使应用程序开发体验更加愉快.该spring-boot-devtools模块可以包含在任何项目 ...

  9. 京东一面:Spring Boot 如何热加载jar实现动态插件?

    一.背景 动态插件化编程是一件很酷的事情,能实现业务功能的 解耦 便于维护,另外也可以提升 可扩展性 随时可以在不停服务器的情况下扩展功能,也具有非常好的 开放性 除了自己的研发人员可以开发功能之外, ...

最新文章

  1. 布局自动驾驶L3级,探访北汽福田发动机生产基地!
  2. no scp yes 不提示_linux脚本实现scp命令自动输入密码和yes/no等确认信息
  3. linux下开启程序崩溃生成core文件开关之ulimit详解
  4. 通过数组名遍历整个数组
  5. css打印适应纸张_从生态平衡到打印机故障分析
  6. php msgid排重,如何应用php数组对百万数据停止排重
  7. vue写的页面title中ico图标不显示的问题
  8. 看懂这些代码,我哭着笑了
  9. C++生产和使用的临时对象
  10. mongodb的基本操作数据更新
  11. Win系统新建文件夹快捷键
  12. 使用AD域管理您的本地计算机密码
  13. js动态显示实时时间
  14. 2018-9-15AGV项目笔记
  15. Footprint:Aave VS Compound之战,谁更能脱颖而出?
  16. unity怎么显示骨骼_Unity3d教程:骨骼动画介绍
  17. 增长率用计算机怎么算,增长率计算公式(excel公式来计算平均增长率的方法)...
  18. 计算机中应用管理在哪里,应用程序管理器在哪里
  19. 数字图像处理学习总结(1):灰度变换与空间滤波
  20. bandit agent下棋AI(python编写) 通过强化学习RL 使用numpy

热门文章

  1. 基于intellij和meavn的整合开发struts2框架的web程序
  2. 程序员如何坚持写作?
  3. Centos 6 安装 配置 oracle11g R2
  4. Nginx的File not found 错误解决
  5. Linux 3.0发布
  6. ExtJs 备忘录(6)—— GirdPanl表格(二) [ 搜索分页 ]
  7. “外星人”字符串生成算法研究
  8. mui ajax ab,mui.ajax中文乱码
  9. python简单爬虫程序分析_[Python专题学习]-python开发简单爬虫
  10. 团队编程项目3-学生成绩管理系统-模块开发过程