技术背景:
做SDK开发的同学会遇到一个问题,需要将某些流程提供给第三方进行扩展。 本文将提供一种扩展策略。
业务背景:
导入数据做持久化时,在持久化前后做一些操作。如:1.在持久化前自定义修改数据,在持久化后记录插入数据成功后,自定义日志信息。2.在验证Excel数据是否合法时
设计思想:
借用了阿里COLA框架的思想,进行代码演变,更符合我现有的业务。 扩展点的设计类似与AOP,与AOP的不同点是扩展点可以在程序内任意代码中进行埋点。
1.申明执行扩展点方法,带返回值和不带返回值两种。
public abstract class AbstractComponentExecutor {
public <R, T> R execute(Class<T> targetClz, Function<T, R> exeFunction) {
T component = locateComponent(targetClz);
return exeFunction.apply(component);
}
public <T> void executeVoid(Class<T> targetClz, Consumer<T> exeFunction) {
T component = locateComponent(targetClz);
exeFunction.accept(component);
}
protected abstract <C> C locateComponent(Class<C> targetClz);
}
2.创建执行器。
@Slf4j
@Component
public class ExtensionExecutor extends AbstractComponentExecutor {
@Resource
private StrategyFactory strategyFactory;
@Override
protected <C> C locateComponent(Class<C> targetClz) {
C extension = (C) strategyFactory.getStrategy(targetClz.getName());
if (extension != null) {
return extension;
}
throw new RuntimeException("不能发现扩展点: "+targetClz);
}
}
3.在验证Excel内容是否合法时,标准场景已无法满足需求,使用SDK同学对原有的验证进行扩展。 首先申明接口,并在需要扩展的地方进行埋点。
public interface ValidatorExtension<T> {
public void validator(ImportContext importContext, List<Integer> columnIndexArray);
}
@Autowired
ExtensionExecutor extensionExecutor;
protected void checkColumn(ImportContext importContext, List<Integer> columnIndexList) {
//标准验证逻辑逻辑。。。。
//执行完标准逻辑,对扩展进行埋点
Map<String, ValidatorExtension> beansOfType = SpringContextHolder.getBeansOfType(ValidatorExtension.class);
beansOfType.forEach((k, v) -> {
Type actualTypeArgument = ((ParameterizedType) v.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
Type subActualTypeArgument = ((ParameterizedType) this.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
if (actualTypeArgument.getTypeName().equalsIgnoreCase(subActualTypeArgument.getTypeName())) {
extensionExecutor.executeVoid(v.getClass(), extension -> extension.validator(importContext, columnIndexList));
}
}
);
}
4.使用示例
@Component
public class MyDataExtension implements ValidatorExtension<Data> {
@Override
public void validator(ImportContext importContext, List<Integer> columnIndexArray) {
//扩展Data业务逻辑
}
}
@Component
public class MyStringExtension implements ValidatorExtension<String> {
@Override
public void validator(ImportContext importContext, List<Integer> columnIndexArray) {
//扩展String业务逻辑
}
}
运行结果
标准 Data业务逻辑
扩展 Data业务逻辑
标准 String业务逻辑
扩展 String业务逻辑