mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-07-01 12:57:26 +00:00
[Update] Core 增加 CacheStore 存储源过滤;
[Add] FactoryInfo 增加 source 属性; [Add] CacheStoreBuilder 增加对存储源的指定; [Add] CacheStoreBuilderTest 调整测试用例以对存储源过滤进行测试(但该测试依然是不完善的, 有待改进);
This commit is contained in:
@ -37,13 +37,13 @@ import java.util.function.Function;
|
|||||||
public class CacheStoreBuilder {
|
public class CacheStoreBuilder {
|
||||||
|
|
||||||
private final static Logger log = LoggerFactory.getLogger(CacheStoreBuilder.class);
|
private final static Logger log = LoggerFactory.getLogger(CacheStoreBuilder.class);
|
||||||
private final static List<CacheStoreFactory> FACTORY_LIST = new LinkedList<>();
|
private final static List<CacheStoreFactory> FACTORY_LIST = new ArrayList<>();
|
||||||
private final static Map<CacheStoreFactory, FactoryInfo> FACTORY_INFO_MAP = new Hashtable<>();
|
private final static Map<CacheStoreFactory, FactoryInfo> FACTORY_INFO_MAP = new Hashtable<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用 SPI 机制加载所有缓存组件.
|
* 使用 SPI 机制加载所有缓存组件.
|
||||||
*
|
*
|
||||||
* <p>第一次执行时加载, 由 {@link #getFactory(Function)} 调用.
|
* <p>第一次执行时加载, 由 {@link #getFactory(CacheStoreSource, Function)} 调用.
|
||||||
* <p>由于 ServiceLoader 线程不安全, 所以通过 synchronized 保证其安全性.
|
* <p>由于 ServiceLoader 线程不安全, 所以通过 synchronized 保证其安全性.
|
||||||
* 不通过 static 块进行初始化的原因是因为担心发生异常导致无法继续执行
|
* 不通过 static 块进行初始化的原因是因为担心发生异常导致无法继续执行
|
||||||
* (除非必要, 否则不要使用 static 执行可能会发生异常的代码.).
|
* (除非必要, 否则不要使用 static 执行可能会发生异常的代码.).
|
||||||
@ -97,7 +97,8 @@ public class CacheStoreBuilder {
|
|||||||
* 获取一个当前可用的高优先级 Factory 对象.
|
* 获取一个当前可用的高优先级 Factory 对象.
|
||||||
* @return 返回可用的高优先级 Factory 对象.
|
* @return 返回可用的高优先级 Factory 对象.
|
||||||
*/
|
*/
|
||||||
private static <R extends CacheStore<?>> R getFactory(Function<CacheStoreFactory, R> function) throws NoSuchFactoryException {
|
private static <R extends CacheStore<?>> R getFactory(CacheStoreSource storeSource, Function<CacheStoreFactory, R> function)
|
||||||
|
throws NoSuchFactoryException {
|
||||||
if (FACTORY_LIST.size() == 0) {
|
if (FACTORY_LIST.size() == 0) {
|
||||||
loadFactory();
|
loadFactory();
|
||||||
}
|
}
|
||||||
@ -105,6 +106,9 @@ public class CacheStoreBuilder {
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
CacheStoreFactory factory = iterator.next();
|
CacheStoreFactory factory = iterator.next();
|
||||||
FactoryInfo info = FACTORY_INFO_MAP.get(factory);
|
FactoryInfo info = FACTORY_INFO_MAP.get(factory);
|
||||||
|
if (storeSource != null && info.getStoreSource() != storeSource) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (factory.canGetCacheStore()) {
|
if (factory.canGetCacheStore()) {
|
||||||
log.debug("CacheStoreFactory {} 可用(优先级: {}).", info.getFactoryName(), info.getFactoryPriority());
|
log.debug("CacheStoreFactory {} 可用(优先级: {}).", info.getFactoryName(), info.getFactoryPriority());
|
||||||
@ -149,8 +153,21 @@ public class CacheStoreBuilder {
|
|||||||
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
*/
|
*/
|
||||||
public static <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) {
|
public static <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) {
|
||||||
|
return newSingleCacheStore(null, identify, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单项缓存存储容器.
|
||||||
|
* @param storeSource 存储类型.
|
||||||
|
* @param identify 缓存容器标识.
|
||||||
|
* @param converter 类型转换器.
|
||||||
|
* @param <V> 值类型.
|
||||||
|
* @return 返回新的存储容器, 与其他容器互不干扰.
|
||||||
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
|
*/
|
||||||
|
public static <V> SingleCacheStore<V> newSingleCacheStore(CacheStoreSource storeSource, String identify, StringConverter<V> converter) {
|
||||||
try {
|
try {
|
||||||
return getFactory(factory -> {
|
return getFactory(storeSource, factory -> {
|
||||||
SingleCacheStore<V> singleCacheStoreInstance = factory.newSingleCacheStore(identify, converter);
|
SingleCacheStore<V> singleCacheStoreInstance = factory.newSingleCacheStore(identify, converter);
|
||||||
if (singleCacheStoreInstance == null) {
|
if (singleCacheStoreInstance == null) {
|
||||||
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
||||||
@ -171,8 +188,21 @@ public class CacheStoreBuilder {
|
|||||||
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
*/
|
*/
|
||||||
public static <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) {
|
public static <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) {
|
||||||
|
return newListCacheStore(null, identify, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列表缓存存储容器.
|
||||||
|
* @param storeSource 存储类型.
|
||||||
|
* @param identify 缓存容器标识.
|
||||||
|
* @param converter 类型转换器.
|
||||||
|
* @param <E> 元素类型.
|
||||||
|
* @return 返回新的存储容器, 与其他容器互不干扰.
|
||||||
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
|
*/
|
||||||
|
public static <E> ListCacheStore<E> newListCacheStore(CacheStoreSource storeSource, String identify, StringConverter<E> converter) {
|
||||||
try {
|
try {
|
||||||
return getFactory(factory -> {
|
return getFactory(storeSource, factory -> {
|
||||||
ListCacheStore<E> listCacheStoreInstance = factory.newListCacheStore(identify, converter);
|
ListCacheStore<E> listCacheStoreInstance = factory.newListCacheStore(identify, converter);
|
||||||
if (listCacheStoreInstance == null) {
|
if (listCacheStoreInstance == null) {
|
||||||
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
||||||
@ -193,8 +223,20 @@ public class CacheStoreBuilder {
|
|||||||
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
*/
|
*/
|
||||||
public static <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) {
|
public static <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) {
|
||||||
|
return newSetCacheStore(null, identify, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取集合缓存存储容器.
|
||||||
|
* @param identify 缓存容器标识.
|
||||||
|
* @param converter 类型转换器.
|
||||||
|
* @param <E> 元素类型.
|
||||||
|
* @return 返回新的存储容器, 与其他容器互不干扰.
|
||||||
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
|
*/
|
||||||
|
public static <E> SetCacheStore<E> newSetCacheStore(CacheStoreSource storeSource, String identify, StringConverter<E> converter) {
|
||||||
try {
|
try {
|
||||||
return getFactory(factory -> {
|
return getFactory(storeSource, factory -> {
|
||||||
SetCacheStore<E> setCacheStoreInstance = factory.newSetCacheStore(identify, converter);
|
SetCacheStore<E> setCacheStoreInstance = factory.newSetCacheStore(identify, converter);
|
||||||
if (setCacheStoreInstance == null) {
|
if (setCacheStoreInstance == null) {
|
||||||
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
||||||
@ -215,8 +257,21 @@ public class CacheStoreBuilder {
|
|||||||
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
*/
|
*/
|
||||||
public static <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) {
|
public static <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) {
|
||||||
|
return newMapCacheStore(null, identify, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取映射表缓存存储容器.
|
||||||
|
* @param storeSource 存储类型.
|
||||||
|
* @param identify 缓存容器标识.
|
||||||
|
* @param converter 类型转换器.
|
||||||
|
* @param <V> 值类型.
|
||||||
|
* @return 返回新的存储容器, 与其他容器互不干扰.
|
||||||
|
* @throws GetCacheStoreException 当无法获取可用的 CacheStore 时抛出.
|
||||||
|
*/
|
||||||
|
public static <V> MapCacheStore<V> newMapCacheStore(CacheStoreSource storeSource, String identify, StringConverter<V> converter) {
|
||||||
try {
|
try {
|
||||||
return getFactory(factory -> {
|
return getFactory(storeSource, factory -> {
|
||||||
MapCacheStore<V> mapCacheStoreInstance = factory.newMapCacheStore(identify, converter);
|
MapCacheStore<V> mapCacheStoreInstance = factory.newMapCacheStore(identify, converter);
|
||||||
if (mapCacheStoreInstance == null) {
|
if (mapCacheStoreInstance == null) {
|
||||||
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
|
||||||
|
@ -29,6 +29,7 @@ public class FactoryInfo {
|
|||||||
|
|
||||||
private final String factoryName;
|
private final String factoryName;
|
||||||
private final int factoryPriority;
|
private final int factoryPriority;
|
||||||
|
private final CacheStoreSource storeSource;
|
||||||
|
|
||||||
public FactoryInfo(Class<? extends CacheStoreFactory> factoryClass) {
|
public FactoryInfo(Class<? extends CacheStoreFactory> factoryClass) {
|
||||||
Factory factoryAnnotation = factoryClass.getAnnotation(Factory.class);
|
Factory factoryAnnotation = factoryClass.getAnnotation(Factory.class);
|
||||||
@ -39,6 +40,7 @@ public class FactoryInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.factoryName = factoryAnnotation.name();
|
this.factoryName = factoryAnnotation.name();
|
||||||
|
this.storeSource = factoryAnnotation.source();
|
||||||
int factoryPriority = factoryAnnotation.priority();
|
int factoryPriority = factoryAnnotation.priority();
|
||||||
if (factoryPriority > FactoryPriority.PRIORITY_HIGHEST) {
|
if (factoryPriority > FactoryPriority.PRIORITY_HIGHEST) {
|
||||||
this.factoryPriority = FactoryPriority.PRIORITY_HIGHEST;
|
this.factoryPriority = FactoryPriority.PRIORITY_HIGHEST;
|
||||||
@ -65,6 +67,14 @@ public class FactoryInfo {
|
|||||||
return factoryPriority;
|
return factoryPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储容器实现的存储源类型.
|
||||||
|
* @return 返回 Factory 所属实现组件的存储源类型.
|
||||||
|
*/
|
||||||
|
public CacheStoreSource getStoreSource() {
|
||||||
|
return storeSource;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
|
@ -32,9 +32,9 @@ public class CacheStoreBuilderTest {
|
|||||||
final String identify = "test";
|
final String identify = "test";
|
||||||
final StringConverter<String> converter = new StringToStringConverter();
|
final StringConverter<String> converter = new StringToStringConverter();
|
||||||
|
|
||||||
Assert.assertNotNull(CacheStoreBuilder.newSingleCacheStore(identify, converter));
|
Assert.assertNotNull(CacheStoreBuilder.newSingleCacheStore(CacheStoreSource.REMOTE, identify, converter));
|
||||||
Assert.assertNotNull(CacheStoreBuilder.newListCacheStore(identify, converter));
|
Assert.assertNotNull(CacheStoreBuilder.newListCacheStore(CacheStoreSource.MEMORY, identify, converter));
|
||||||
Assert.assertNotNull(CacheStoreBuilder.newMapCacheStore(identify, converter));
|
Assert.assertNotNull(CacheStoreBuilder.newMapCacheStore(CacheStoreSource.REMOTE, identify, converter));
|
||||||
Assert.assertNotNull(CacheStoreBuilder.newSetCacheStore(identify, converter));
|
Assert.assertNotNull(CacheStoreBuilder.newSetCacheStore(identify, converter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user