
1、前提
- 首先参考该博文–》
spring boot 动态加载模块(加载外部jar包) - 但我要说的是加载的方式可以是有多种的,不一定是需要打包成jar包,也可以直接是字节码文件。
- 具体怎么做可以自行研究一下,不会的可以评论提问,在此就不说了,不是重点。
- 照图中的方法将Service和Mapper在加载前进行一次特殊化处理,即动态代理。
- 注意,图中使用的是GenericBeanDefinition,与上文的博主用的有区别。
- 图中在注入Service层时使用的是一个自定义的动态代理,具体怎么用请学习JDK动态代理和CGLIB动态代理相关知识。也可参考:SpringAOP详解(第二次学习Spring,主要是JDK动态代理)
- 在第一次加载完后,你会发现,如果移除完后,在不重启项目的情况下再次加载相关类就会出现问题。这是因为移除的时候并未完全移除掉相关的mapper方法,所以我们需要重写MapperFactoryBean类中的checkDaoConfig方法,让其在代理注入的时候先把残留的注入移除干净。
@Override
protected void checkDaoConfig() {
super.checkDaoConfig();
Assert.notNull(this.mapperInterface, "Property 'mapperInterface' is required");
Configuration configuration = this.getSqlSession().getConfiguration();
String interfaceName = this.mapperInterface.getName();
// 清除已存的残留 重要修改的地方
boolean isSupper = configuration.getClass().getSuperclass() == Configuration.class;
try {
Field loadedResourcesField = isSupper
? configuration.getClass().getSuperclass().getDeclaredField("loadedResources")
: configuration.getClass().getDeclaredField("loadedResources");
loadedResourcesField.setAccessible(true);
Set loadedResourcesSet = ((Set) loadedResourcesField.get(configuration));
loadedResourcesSet.remove("interface " + interfaceName);
Set mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(configuration);
mapperRegistryCache.remove("interface " + interfaceName);
Field knownMappers = MybatisMapperRegistry.class.getDeclaredField("knownMappers");
knownMappers.setAccessible(true);
Map, MapperProxyFactory>> knownMappersMap = (Map, MapperProxyFactory>>)
knownMappers.get(configuration.getMapperRegistry());
for (Class> key : knownMappersMap.keySet()) {
if (key.getName().startsWith(interfaceName.substring(0, interfaceName.lastIndexOf(".")))){
knownMappersMap.remove(key);
logger.info("移除残留的knownMappersMap:" + key.getName());
break;
}
}
Collection mappedStatements = configuration.getMappedStatements();
List objects = Lists.newArrayList();
for (Object object : mappedStatements) {
if (object instanceof MappedStatement) {
MappedStatement mappedStatement = (MappedStatement) object;
if (mappedStatement.getId().startsWith(interfaceName)) {
objects.add(mappedStatement);
}
}
}
mappedStatements.removeAll(objects);
SqlSessionTemplate sqlSessionTemplate = this.getSqlSessionTemplate();
sqlSessionTemplate.flushStatements();
} catch (Exception e) {
logger.error("Refresh IOException :" + e.getMessage());
}
if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
try {
configuration.addMapper(this.mapperInterface);
} catch (Exception var6) {
this.logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", var6);
throw new IllegalArgumentException(var6);
} finally {
ErrorContext.instance().reset();
}
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)