springboot+mybatis热启动 您所在的位置:网站首页 icpoes操作方法热开机预热74min springboot+mybatis热启动

springboot+mybatis热启动

2024-07-09 20:25| 来源: 网络整理| 查看: 265

參考:https://blog.csdn.net/angry_mills/article/details/80565863

 springboot     2.0.0.RELEASE    

 mybatis    3.4.5

mybatis-spring-boot-starter    1.3.0

MapperRefresh 类有点小改动:

package cn.com.do1.component.build.sz.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.net.URL; import java.util.*; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.session.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.NestedIOException; import org.springframework.core.io.Resource; import com.google.common.collect.Sets; /** * 刷新MyBatis Mapper XML 线程 * @author juane * @version 2019-3-03 */ public class MapperRefresh implements java.lang.Runnable { public static Logger log = LoggerFactory.getLogger(MapperRefresh.class); private static String filename = "mybatis-refresh.properties"; private static Properties prop = new Properties(); private static boolean enabled; // 是否启用Mapper刷新线程功能 private static boolean refresh; // 刷新启用后,是否启动了刷新线程 private Set location; // Mapper实际资源路径 private Resource[] mapperLocations; // Mapper资源路径 private Configuration configuration; // MyBatis配置对象 private Long beforeTime = 0L; // 上一次刷新时间 private static int delaySeconds; // 延迟刷新秒数 private static int sleepSeconds; // 休眠时间 private static String mappingPath; // xml文件夹匹配字符串,需要根据需要修改 static { // try { // prop.load(MapperRefresh.class.getResourceAsStream(filename)); // } catch (Exception e) { // e.printStackTrace(); // System.out.println("Load mybatis-refresh “"+filename+"” file error."); // } URL url = MapperRefresh.class.getClassLoader().getResource(filename); InputStream is; try { is = url.openStream(); if (is == null) { log.warn("applicationConfig.properties not found."); } else { prop.load(is); } } catch (IOException e) { e.printStackTrace(); } String value = getPropString("enabled"); System.out.println(value); enabled = "true".equalsIgnoreCase(value); delaySeconds = getPropInt("delaySeconds"); sleepSeconds = getPropInt("sleepSeconds"); mappingPath = getPropString("mappingPath"); delaySeconds = delaySeconds == 0 ? 50 : delaySeconds; sleepSeconds = sleepSeconds == 0 ? 3 : sleepSeconds; mappingPath = StringUtils.isBlank(mappingPath) ? "mappings" : mappingPath; log.debug("[enabled] " + enabled); log.debug("[delaySeconds] " + delaySeconds); log.debug("[sleepSeconds] " + sleepSeconds); log.debug("[mappingPath] " + mappingPath); } public static boolean isRefresh() { return refresh; } public MapperRefresh(Resource[] mapperLocations, Configuration configuration) { this.mapperLocations = mapperLocations; this.configuration = configuration; } @Override public void run() { beforeTime = System.currentTimeMillis(); log.debug("[location] " + location); log.debug("[configuration] " + configuration); if (enabled) { // 启动刷新线程 final MapperRefresh runnable = this; new Thread(new java.lang.Runnable() { @Override public void run() { if (location == null){ location = Sets.newHashSet(); log.debug("MapperLocation's length:" + mapperLocations.length); for (Resource mapperLocation : mapperLocations) { String s = mapperLocation.toString().replaceAll("\\\\", "/"); s = s.substring("file [".length(), s.lastIndexOf(mappingPath) + mappingPath.length()); if (!location.contains(s)) { location.add(s); log.debug("Location:" + s); } } log.debug("Locarion's size:" + location.size()); } try { Thread.sleep(delaySeconds * 1000); } catch (InterruptedException e2) { e2.printStackTrace(); } refresh = true; System.out.println("========= Enabled refresh mybatis mapper ========="); while (true) { try { for (String s : location) { runnable.refresh(s, beforeTime); } } catch (Exception e1) { e1.printStackTrace(); } try { Thread.sleep(sleepSeconds * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "MyBatis-Mapper-Refresh").start(); } } /** * 执行刷新 * @param filePath 刷新目录 * @param beforeTime 上次刷新时间 * @throws NestedIOException 解析异常 * @throws FileNotFoundException 文件未找到 * @author ThinkGem */ @SuppressWarnings({ "rawtypes", "unchecked" }) private void refresh(String filePath, Long beforeTime) throws Exception { // 本次刷新时间 Long refrehTime = System.currentTimeMillis(); // 获取需要刷新的Mapper文件列表 List fileList = this.getRefreshFile(new File(filePath), beforeTime); if (fileList.size() > 0) { log.debug("Refresh file: " + fileList.size()); } for (int i = 0; i < fileList.size(); i++) { InputStream inputStream = new FileInputStream(fileList.get(i)); String resource = fileList.get(i).getAbsolutePath(); try { // 清理原有资源,更新为自己的StrictMap方便,增量重新加载 String[] mapFieldNames = new String[]{ "mappedStatements", "caches", "resultMaps", "parameterMaps", "keyGenerators", "sqlFragments" }; Map fieldMap = new HashMap() ; Class tempClass2 = configuration.getClass(); while (tempClass2 != null) {//当父类为null的时候说明到达了最上层的父类(Object类). for(Field f : Arrays.asList(tempClass2 .getDeclaredFields())) { fieldMap.put(f.getName(),f); } tempClass2 = tempClass2.getSuperclass(); //得到父类,然后赋给自己 } Class tempClass = configuration.getClass().getSuperclass(); for (String fieldName : mapFieldNames){ Field field = tempClass.getDeclaredField(fieldName); field.setAccessible(true); Map map = ((Map)field.get(configuration)); if (!(map instanceof StrictMap)){ Map newMap = new StrictMap(StringUtils.capitalize(fieldName) + "collection"); for (Object key : map.keySet()){ try { newMap.put(key, map.get(key)); }catch(IllegalArgumentException ex){ newMap.put(key, ex.getMessage()); } } field.set(configuration, newMap); } } // 清理已加载的资源标识,方便让它重新加载。 Field loadedResourcesField = tempClass.getDeclaredField("loadedResources"); loadedResourcesField.setAccessible(true); Set loadedResourcesSet = ((Set)loadedResourcesField.get(configuration)); loadedResourcesSet.remove(resource); //重新编译加载资源文件。 XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); xmlMapperBuilder.parse(); } catch (Exception e) { throw new NestedIOException("Failed to parse mapping resource: '" + resource + "'", e); } finally { ErrorContext.instance().reset(); } // System.out.println("Refresh file: " + mappingPath + StringUtils.substringAfterLast(fileList.get(i).getAbsolutePath(), mappingPath)); if (log.isDebugEnabled()) { log.debug("Refresh file: " + fileList.get(i).getAbsolutePath()); log.debug("Refresh filename: " + fileList.get(i).getName()); } } // 如果刷新了文件,则修改刷新时间,否则不修改 if (fileList.size() > 0) { this.beforeTime = refrehTime; } } /** * 获取需要刷新的文件列表 * @param dir 目录 * @param beforeTime 上次刷新时间 * @return 刷新文件列表 */ private List getRefreshFile(File dir, Long beforeTime) { List fileList = new ArrayList(); File[] files = dir.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.isDirectory()) { fileList.addAll(this.getRefreshFile(file, beforeTime)); } else if (file.isFile()) { if (this.checkFile(file, beforeTime)) { fileList.add(file); } } else { System.out.println("Error file." + file.getName()); } } } return fileList; } /** * 判断文件是否需要刷新 * @param file 文件 * @param beforeTime 上次刷新时间 * @return 需要刷新返回true,否则返回false */ private boolean checkFile(File file, Long beforeTime) { if (file.lastModified() > beforeTime) { return true; } return false; } /** * 获取整数属性 * @param key * @return */ private static int getPropInt(String key) { int i = 0; try { i = Integer.parseInt(getPropString(key)); } catch (Exception e) { } return i; } /** * 获取字符串属性 * @param key * @return */ private static String getPropString(String key) { return prop == null ? null : prop.getProperty(key).trim(); } /** * 重写 org.apache.ibatis.session.Configuration.StrictMap 类 * 来自 MyBatis3.4.0版本,修改 put 方法,允许反复 put更新。 */ public static class StrictMap extends HashMap { private static final long serialVersionUID = -4950446264854982944L; private String name; public StrictMap(String name, int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); this.name = name; } public StrictMap(String name, int initialCapacity) { super(initialCapacity); this.name = name; } public StrictMap(String name) { super(); this.name = name; } public StrictMap(String name, Map m) { super(m); this.name = name; } @SuppressWarnings("unchecked") public V put(String key, V value) { // ThinkGem 如果现在状态为刷新,则刷新(先删除后添加) if (MapperRefresh.isRefresh()) { remove(key); // MapperRefresh.log.debug("refresh key:" + key.substring(key.lastIndexOf(".") + 1)); } // ThinkGem end if (containsKey(key)) { throw new IllegalArgumentException(name + " already contains value for " + key); } if (key.contains(".")) { final String shortKey = getShortName(key); if (super.get(shortKey) == null) { super.put(shortKey, value); } else { super.put(shortKey, (V) new Ambiguity(shortKey)); } } return super.put(key, value); } public V get(Object key) { V value = super.get(key); if (value == null) { throw new IllegalArgumentException(name + " does not contain value for " + key); } if (value instanceof Ambiguity) { throw new IllegalArgumentException(((Ambiguity) value).getSubject() + " is ambiguous in " + name + " (try using the full name including the namespace, or rename one of the entries)"); } return value; } private String getShortName(String key) { final String[] keyparts = key.split("\\."); return keyparts[keyparts.length - 1]; } protected static class Ambiguity { private String subject; public Ambiguity(String subject) { this.subject = subject; } public String getSubject() { return subject; } } } }

启动类:

@Autowired private SqlSession sqlSession; @PostConstruct public void postConstruct() throws IOException { //Constant.threadPool = Executors.newFixedThreadPool(20); Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath*:**/mapper/*/*Dao.xml"); org.apache.ibatis.session.Configuration configuration = (org.apache.ibatis.session.Configuration)sqlSession.getConfiguration(); new MapperRefresh(resources, configuration).run(); }

改了XML之后,build一下。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有