mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
support spi
This commit is contained in:
parent
85c9dae9ae
commit
bd6b07f6b9
@ -15,6 +15,7 @@
|
||||
* 【core 】 增加ServiceLoaderUtil
|
||||
* 【core 】 增加EnumUtil.getEnumAt方法
|
||||
* 【core 】 增强EnumConvert判断能力(issue#I17082@Gitee)
|
||||
* 【log 】 使用SPI机制代替硬编码
|
||||
|
||||
### Bug修复
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
@ -18,6 +19,25 @@ import java.util.ServiceLoader;
|
||||
*/
|
||||
public class ServiceLoaderUtil {
|
||||
|
||||
/**
|
||||
* 加载第一个可用服务,如果用户定义了多个接口实现类,只获取第一个不报错的服务。
|
||||
*
|
||||
* @param <T> 接口类型
|
||||
* @param clazz 服务接口
|
||||
* @return 第一个服务接口实现对象,无实现返回{@code null}
|
||||
*/
|
||||
public static <T> T loadFirstAvailable(Class<T> clazz) {
|
||||
final Iterator<T> iterator = load(clazz).iterator();
|
||||
if(iterator.hasNext()){
|
||||
try {
|
||||
return iterator.next();
|
||||
} catch (ServiceConfigurationError e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载第一个服务,如果用户定义了多个接口实现类,只获取第一个。
|
||||
*
|
||||
|
@ -1,24 +1,17 @@
|
||||
package cn.hutool.extra.template.engine;
|
||||
|
||||
import com.jfinal.template.Engine;
|
||||
|
||||
import cn.hutool.core.util.ServiceLoaderUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.template.TemplateConfig;
|
||||
import cn.hutool.extra.template.TemplateEngine;
|
||||
import cn.hutool.extra.template.TemplateException;
|
||||
import cn.hutool.extra.template.engine.beetl.BeetlEngine;
|
||||
import cn.hutool.extra.template.engine.enjoy.EnjoyEngine;
|
||||
import cn.hutool.extra.template.engine.freemarker.FreemarkerEngine;
|
||||
import cn.hutool.extra.template.engine.rythm.RythmEngine;
|
||||
import cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
|
||||
import cn.hutool.extra.template.engine.velocity.VelocityEngine;
|
||||
import cn.hutool.log.StaticLog;
|
||||
import com.jfinal.template.Engine;
|
||||
|
||||
/**
|
||||
* 简单模板工厂,用于根据用户引入的模板引擎jar,自动创建对应的模板引擎对象
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class TemplateFactory {
|
||||
/**
|
||||
@ -42,36 +35,11 @@ public class TemplateFactory {
|
||||
* @return {@link Engine}
|
||||
*/
|
||||
private static TemplateEngine doCreate(TemplateConfig config) {
|
||||
try {
|
||||
return new BeetlEngine(config);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new FreemarkerEngine(config);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new VelocityEngine(config);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new RythmEngine(config);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new EnjoyEngine(config);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new ThymeleafEngine(config);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
final TemplateEngine engine = ServiceLoaderUtil.loadFirstAvailable(TemplateEngine.class);
|
||||
if(null != engine){
|
||||
return engine;
|
||||
}
|
||||
|
||||
throw new TemplateException("No template found ! Please add one of template jar to your project !");
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,9 @@
|
||||
package cn.hutool.extra.tokenizer.engine;
|
||||
|
||||
import cn.hutool.core.util.ServiceLoaderUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.tokenizer.TokenizerEngine;
|
||||
import cn.hutool.extra.tokenizer.TokenizerException;
|
||||
import cn.hutool.extra.tokenizer.engine.analysis.SmartcnEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.ansj.AnsjEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.hanlp.HanLPEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.ikanalyzer.IKAnalyzerEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.jcseg.JcsegEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.jieba.JiebaEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.mmseg.MmsegEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.mynlp.MynlpEngine;
|
||||
import cn.hutool.extra.tokenizer.engine.word.WordEngine;
|
||||
import cn.hutool.log.StaticLog;
|
||||
|
||||
/**
|
||||
@ -38,51 +30,11 @@ public class TokenizerFactory {
|
||||
* @return {@link TokenizerEngine}
|
||||
*/
|
||||
private static TokenizerEngine doCreate() {
|
||||
try {
|
||||
return new AnsjEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new HanLPEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new IKAnalyzerEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new JcsegEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new JiebaEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new MmsegEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new WordEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new SmartcnEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
return new MynlpEngine();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
final TokenizerEngine engine = ServiceLoaderUtil.loadFirstAvailable(TokenizerEngine.class);
|
||||
if(null != engine){
|
||||
return engine;
|
||||
}
|
||||
|
||||
throw new TokenizerException("No tokenizer found ! Please add some tokenizer jar to your project !");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
cn.hutool.extra.template.engine.beetl.BeetlEngine
|
||||
cn.hutool.extra.template.engine.freemarker.FreemarkerEngine
|
||||
cn.hutool.extra.template.engine.velocity.VelocityEngine
|
||||
cn.hutool.extra.template.engine.rythm.RythmEngine
|
||||
cn.hutool.extra.template.engine.enjoy.EnjoyEngine
|
||||
cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine
|
@ -0,0 +1,9 @@
|
||||
cn.hutool.extra.tokenizer.engine.ansj.AnsjEngine
|
||||
cn.hutool.extra.tokenizer.engine.hanlp.HanLPEngine
|
||||
cn.hutool.extra.tokenizer.engine.ikanalyzer.IKAnalyzerEngine
|
||||
cn.hutool.extra.tokenizer.engine.jcseg.JcsegEngine
|
||||
cn.hutool.extra.tokenizer.engine.jieba.JiebaEngine
|
||||
cn.hutool.extra.tokenizer.engine.mmseg.MmsegEngine
|
||||
cn.hutool.extra.tokenizer.engine.word.WordEngine
|
||||
cn.hutool.extra.tokenizer.engine.analysis.SmartcnEngine
|
||||
cn.hutool.extra.tokenizer.engine.mynlp.MynlpEngine
|
@ -14,13 +14,12 @@ import cn.hutool.log.dialect.tinylog.TinyLogFactory;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 日志工厂类
|
||||
*
|
||||
* @author Looly
|
||||
* @see Slf4jLogFactory
|
||||
* @see Log4j2LogFactory
|
||||
* @see Log4jLogFactory
|
||||
@ -29,15 +28,16 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* @see JbossLogFactory
|
||||
* @see ConsoleLogFactory
|
||||
* @see JdkLogFactory
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public abstract class LogFactory {
|
||||
|
||||
/** 日志框架名,用于打印当前所用日志框架 */
|
||||
/**
|
||||
* 日志框架名,用于打印当前所用日志框架
|
||||
*/
|
||||
protected String name;
|
||||
/** 日志对象缓存 */
|
||||
/**
|
||||
* 日志对象缓存
|
||||
*/
|
||||
private Map<Object, Log> logCache;
|
||||
|
||||
/**
|
||||
@ -118,6 +118,7 @@ public abstract class LogFactory {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------- Static start
|
||||
|
||||
/**
|
||||
* @return 当前使用的日志工厂
|
||||
*/
|
||||
@ -128,6 +129,8 @@ public abstract class LogFactory {
|
||||
/**
|
||||
* 自定义日志实现
|
||||
*
|
||||
* @param logFactoryClass 日志工厂类
|
||||
* @return 自定义的日志工厂类
|
||||
* @see Slf4jLogFactory
|
||||
* @see Log4j2LogFactory
|
||||
* @see Log4jLogFactory
|
||||
@ -136,9 +139,6 @@ public abstract class LogFactory {
|
||||
* @see JbossLogFactory
|
||||
* @see ConsoleLogFactory
|
||||
* @see JdkLogFactory
|
||||
*
|
||||
* @param logFactoryClass 日志工厂类
|
||||
* @return 自定义的日志工厂类
|
||||
*/
|
||||
public static LogFactory setCurrentLogFactory(Class<? extends LogFactory> logFactoryClass) {
|
||||
return GlobalLogFactory.set(logFactoryClass);
|
||||
@ -147,6 +147,8 @@ public abstract class LogFactory {
|
||||
/**
|
||||
* 自定义日志实现
|
||||
*
|
||||
* @param logFactory 日志工厂类对象
|
||||
* @return 自定义的日志工厂类
|
||||
* @see Slf4jLogFactory
|
||||
* @see Log4j2LogFactory
|
||||
* @see Log4jLogFactory
|
||||
@ -155,9 +157,6 @@ public abstract class LogFactory {
|
||||
* @see JbossLogFactory
|
||||
* @see ConsoleLogFactory
|
||||
* @see JdkLogFactory
|
||||
*
|
||||
* @param logFactory 日志工厂类对象
|
||||
* @return 自定义的日志工厂类
|
||||
*/
|
||||
public static LogFactory setCurrentLogFactory(LogFactory logFactory) {
|
||||
return GlobalLogFactory.set(logFactory);
|
||||
@ -195,6 +194,7 @@ public abstract class LogFactory {
|
||||
* <p>
|
||||
* 依次按照顺序检查日志库的jar是否被引入,如果未引入任何日志库,则检查ClassPath下的logging.properties,存在则使用JdkLogFactory,否则使用ConsoleLogFactory
|
||||
*
|
||||
* @return 日志实现类
|
||||
* @see Slf4jLogFactory
|
||||
* @see Log4j2LogFactory
|
||||
* @see Log4jLogFactory
|
||||
@ -203,7 +203,6 @@ public abstract class LogFactory {
|
||||
* @see JbossLogFactory
|
||||
* @see ConsoleLogFactory
|
||||
* @see JdkLogFactory
|
||||
* @return 日志实现类
|
||||
*/
|
||||
public static LogFactory create() {
|
||||
final LogFactory factory = doCreate();
|
||||
@ -216,6 +215,7 @@ public abstract class LogFactory {
|
||||
* <p>
|
||||
* 依次按照顺序检查日志库的jar是否被引入,如果未引入任何日志库,则检查ClassPath下的logging.properties,存在则使用JdkLogFactory,否则使用ConsoleLogFactory
|
||||
*
|
||||
* @return 日志实现类
|
||||
* @see Slf4jLogFactory
|
||||
* @see Log4j2LogFactory
|
||||
* @see Log4jLogFactory
|
||||
@ -224,16 +224,11 @@ public abstract class LogFactory {
|
||||
* @see JbossLogFactory
|
||||
* @see ConsoleLogFactory
|
||||
* @see JdkLogFactory
|
||||
* @return 日志实现类
|
||||
*/
|
||||
private static LogFactory doCreate() {
|
||||
final ServiceLoader<LogFactory> factories = ServiceLoaderUtil.load(LogFactory.class);
|
||||
for (LogFactory factory : factories) {
|
||||
try {
|
||||
return factory;
|
||||
} catch (ServiceConfigurationError e) {
|
||||
// ignore
|
||||
}
|
||||
final LogFactory factory = ServiceLoaderUtil.loadFirstAvailable(LogFactory.class);
|
||||
if(null != factory){
|
||||
return factory;
|
||||
}
|
||||
|
||||
// 未找到任何可支持的日志库时判断依据:当JDK Logging的配置文件位于classpath中,使用JDK Logging,否则使用Console
|
||||
|
Loading…
x
Reference in New Issue
Block a user