Spring实现热加载MyBatis 的XML配置文件
生活随笔
收集整理的這篇文章主要介紹了
Spring实现热加载MyBatis 的XML配置文件
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
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,正式環(huán)境需要去掉*/ @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);//?觸發(fā)文件監(jiān)聽事件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();//?移除加載項(xiàng)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();}}}轉(zhuǎn)載于:https://my.oschina.net/houke/blog/282445
總結(jié)
以上是生活随笔為你收集整理的Spring实现热加载MyBatis 的XML配置文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 闲话缓存:算法
- 下一篇: pthread中如何追踪stack ov