Struct Util 权威指南 - 通过 SPI 实现自定义扩展
524 字
3 分钟
Struct Util 权威指南 - 通过 SPI 实现自定义扩展
Struct Util 是一个 Java 语言开发的结构化数据映射处理工具。Struct Util 主要解决两个方面的问题。第一个方面将*.xls, *.csv 等配置友好型数据源转换为业务侧友好型的 bean 结构,对配置数据和使用数据进行解耦,让开发和运营、策划三方实现共赢。第二方面解决了数据表热重载,数据有条件过滤,表结构跨表引用等等应用相关的问题。
StructUtil是博主个人作品, 稍微有自吹自擂的嫌疑, 欢迎:star:收藏。哈哈, 因为是个人作品,应该是足够”权威”了。嘻嘻~~
SPI 扩展
Struct Util 提供了 Converters, Converter, StructFactoryBean, StructHandler四个扩展点,允许用户进行功能扩展。
EnhancedServiceLoader
相比于 JDK 内置的 SPI 功能解决了加载异常处理,懒加载等问题。核心加载代码如下:
void handleDefinitionFile(String dir, ClassLoader classLoader, List<ExtensionDefinition> output) throws IOException { String fileName = dir + this.service.getName(); Enumeration<URL> urls = classLoader != null ? classLoader.getResources(fileName) : ClassLoader.getSystemResources(fileName); while (urls.hasMoreElements()) { URL url = urls.nextElement(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) { String line = null; while (null != (line = reader.readLine())) { line = line.trim(); if (line.length() > 0) { try { output.add(this.createExtensionDefinition(line, classLoader)); } catch (LinkageError | ClassNotFoundException e) { LOGGER.warn("load [{}] class failure. {}", line, e.getMessage()); } } } } catch (Throwable e) { LOGGER.warn("handle extension definition file error.", e); } }}
ExtensionDefinition createExtensionDefinition(String clzName, ClassLoader loader) throws ClassNotFoundException { Class<?> clzOfService = Class.forName(clzName, true, loader); String name = null; int order = 0; SPI anno = AnnotationUtils.findAnnotation(SPI.class, clzOfService); if (anno != null) { name = anno.name(); order = anno.order(); } return new ExtensionDefinition(name, clzOfService, order);}自定义 Converter
Struct Util内置了常用的类型转换器, 当用户有特殊转换需求时,可以通过扩展 Converter 接口实现转换业务,并通过 SPI 机制自动注册到系统中。以下是一个简单的字符串转数组的转换器实例。
public class StringToArrayConverter implements Converter {
@Override public Object convert(Object originValue, Class<?> targetType) { if (!targetType.isArray() || String.class != originValue.getClass()) { return null; } String content = (String) originValue; Class<?> componentType = targetType.getComponentType(); String[] data = content.split(separator); if (exceptBlank) { data = Arrays.stream(data) .map(String::trim) .filter(s -> !s.isEmpty()) .toArray(String[]::new); } Object array = Array.newInstance(componentType, data.length); for (int i = 0; i < data.length; i++) { Array.set(array, i, ConverterUtil.covert(data[i], componentType)); } return array; }}支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
Struct Util 权威指南 - 通过 SPI 实现自定义扩展
https://tinyzzh.github.io/posts/2023-05-01-struct_util_04_spi_custom_extension/ 相关文章 智能推荐
1
Struct Util 权威指南 - 框架简介
JAVA 2023-05-01
2
Struct Util 权威指南 - 基础应用入门实战
JAVA 2023-05-01
3
Struct Util 权威指南 - 与Spring Framework框架集成
JAVA 2023-05-01
4
Struct Util 权威指南 - 集成到Spring Boot全家桶
JAVA 2023-05-01
5
Struct Util 权威指南 - 配置文件的热重载
JAVA 2023-05-01
随机文章 随机推荐