JAVA实现扩展点

请先了解策略组合模式后再查看

技术背景:
做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业务逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值