add cache

This commit is contained in:
Looly 2021-11-19 00:32:51 +08:00
parent 9a756eb4b1
commit 6ed8588c83
2 changed files with 25 additions and 20 deletions

View File

@ -3,7 +3,7 @@
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.7.17 (2021-11-18) # 5.7.17 (2021-11-19)
### 🐣新特性 ### 🐣新特性
* 【core 】 增加AsyncUtilpr#457@Gitee * 【core 】 增加AsyncUtilpr#457@Gitee
@ -18,6 +18,7 @@
* 【core 】 Opt增加部分方法pr#459@Gitee * 【core 】 Opt增加部分方法pr#459@Gitee
* 【core 】 增加DefaultCloneablepr#459@Gitee * 【core 】 增加DefaultCloneablepr#459@Gitee
* 【core 】 CollStreamUtil增加是否并行的重载pr#467@Gitee * 【core 】 CollStreamUtil增加是否并行的重载pr#467@Gitee
* 【core 】 ResourceClassLoader增加缓存pr#1959@Github
* *
### 🐞Bug修复 ### 🐞Bug修复
* 【core 】 修复FileResource构造fileName参数无效问题issue#1942@Github * 【core 】 修复FileResource构造fileName参数无效问题issue#1942@Github

View File

@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil;
import java.security.SecureClassLoader; import java.security.SecureClassLoader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* 资源类加载器可以加载任意类型的资源类 * 资源类加载器可以加载任意类型的资源类
@ -19,11 +18,10 @@ import java.util.concurrent.ConcurrentHashMap;
public class ResourceClassLoader<T extends Resource> extends SecureClassLoader { public class ResourceClassLoader<T extends Resource> extends SecureClassLoader {
private final Map<String, T> resourceMap; private final Map<String, T> resourceMap;
/** /**
* 缓存已经加载的类 * 缓存已经加载的类
*/ */
private final Map<String, Class> cacheClassMap; private final Map<String, Class<?>> cacheClassMap;
/** /**
* 构造 * 构造
@ -34,11 +32,12 @@ public class ResourceClassLoader<T extends Resource> extends SecureClassLoader {
public ResourceClassLoader(ClassLoader parentClassLoader, Map<String, T> resourceMap) { public ResourceClassLoader(ClassLoader parentClassLoader, Map<String, T> resourceMap) {
super(ObjectUtil.defaultIfNull(parentClassLoader, ClassLoaderUtil.getClassLoader())); super(ObjectUtil.defaultIfNull(parentClassLoader, ClassLoaderUtil.getClassLoader()));
this.resourceMap = ObjectUtil.defaultIfNull(resourceMap, new HashMap<>()); this.resourceMap = ObjectUtil.defaultIfNull(resourceMap, new HashMap<>());
this.cacheClassMap = new ConcurrentHashMap<>(); this.cacheClassMap = new HashMap<>();
} }
/** /**
* 增加需要加载的类资源 * 增加需要加载的类资源
*
* @param resource 资源可以是文件流或者字符串 * @param resource 资源可以是文件流或者字符串
* @return this * @return this
*/ */
@ -49,21 +48,26 @@ public class ResourceClassLoader<T extends Resource> extends SecureClassLoader {
@Override @Override
protected Class<?> findClass(String name) throws ClassNotFoundException { protected Class<?> findClass(String name) throws ClassNotFoundException {
final Class<?> clazz = cacheClassMap.computeIfAbsent(name, className -> { final Class<?> clazz = cacheClassMap.computeIfAbsent(name, this::defineByName);
if (clazz == null) {
return super.findClass(name);
}
return clazz;
}
/**
* 从给定资源中读取class的二进制流然后生成类<br>
* 如果这个类资源不存在返回{@code null}
*
* @param name 类名
* @return 定义的类
*/
private Class<?> defineByName(String name) {
final Resource resource = resourceMap.get(name); final Resource resource = resourceMap.get(name);
if (null != resource) { if (null != resource) {
final byte[] bytes = resource.readBytes(); final byte[] bytes = resource.readBytes();
return defineClass(name, bytes, 0, bytes.length); return defineClass(name, bytes, 0, bytes.length);
} }
try {
return super.findClass(name);
} catch (ClassNotFoundException e) {
return null; return null;
} }
});
if (clazz == null) {
throw new ClassNotFoundException(name);
}
return clazz;
}
} }