基于spring容器的动态编排

100 阅读2分钟

动态编排

bean初始化后将执行步骤添加到plots中,具体功能实现依赖plot实现,plot中的功能依赖具体的handler实现,该实现方式不仅能够清晰的通过plot来划分业务边界,使业务代码更易于维护。同时提高了代码的复用性和拓展性。

在这里插入图片描述 spring加载完bean后置处理,获取function类中plot注解,将plot添加到集合中。

@Service
public class BeanPostProcessor extends DefaultPostProcessor {

    private static final Logger logger = LoggerFactory.getLogger(BeanPostProcessor.class);
    /**
     * bean初始化之后执行
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        logger.info("test ->>>>postProcessAfterInitialization 方法执行.....");
        //获取bean的class对象
        Class cls = AopUtils.getTargetClass(bean);

        Function anno = null;
        while (anno == null && cls != null) {
            //获取class上的Function注解
            anno = (Function) cls.getAnnotation(Function.class);
            cls = cls.getSuperclass();
            logger.info("test ->>>>postProcessAfterInitialization 获取class上的Function注解anno:{}",anno);
        }
        if (anno != null) {
            //获取Function注解不为空,则anno为BaseFunction的子类,
            BaseFunction baseFunction = (BaseFunction) bean;
            if (anno.plots() != null && anno.plots().length != 0) {
                logger.info("test ->>>>postProcessAfterInitialization 获取Function注解的plots数组:{}", JSONObject.toJSONString(anno.plots()));
                for (Class filterCls : anno.plots()) {
                    //通过IPlot的class获取IPlot的子类对象
                    IPlot filter = (IPlot) applicationContext.getBean(filterCls);
                    logger.info("test ->>>>postProcessAfterInitialization 获取IPlot getBean:{}", filter);
                    baseFunction.addPlot(filter);
                }
                logger.info("test ->>>>postProcessAfterInitialization baseFunction plotsList:{}", JSONObject.toJSONString(baseFunction.getPlot()));
            }
        }
        return bean;
    }
}

功能类接口,提供执行步骤集合和执行方法入口

public abstract class IFunction<RES,REQ,CONTEXT> {

    private static final Logger logger = LoggerFactory.getLogger(BaseFunction.class);
    /**
     * 编排Plot列表
     */
    protected List<IPlot> plots = new LinkedList<>();

    public ServiceResponse<RES> execute(REQ req) {

        ServiceResponse<RES> rs =  new ServiceResponse<>();
        //当前执行功能名称
        String function = AopUtils.getTargetClass(this).getName();
        try {
            rs = process(req);
        } catch (Exception e){
            logger.error("异常:"+e.getMessage());
        }
        return rs;
    }

    /**
     * 编排执行入口
     * @param req
     * @return
     */
    public ServiceResponse<RES> process(REQ req) throws Exception {
        ServiceResponse<RES> result;
        CONTEXT context = null;

        context = initContext(req); //初始化一个上下文
        result = beforeExecute(req, context);//前置处理
        if (result == null || !result.isSuccess()) {
            return result;
        }
        //获取编排
        ServiceResponse<List<IPlot>> filtersRes = changePlotChain(req, context);
      
        if (filtersRes == null || !filtersRes.isSuccess()) {
            return ServiceResponse.failure();
        }
        //按编排顺序处理
        for (IPlot<RES,REQ,CONTEXT> plot : filtersRes.getResult()) {
            String plotKey = AopUtils.getTargetClass(plot).getName();
   
            result = plot.execute(req, context);

            if (!plot.toNext(result, req, context)) {
                break;
            }
        }
        //后置处理
        result = afterExecute(result, req, context);

        return result;
    }

    /**
     * 前置执行
     *
     * @param req
     * @param context
     */
    protected ServiceResponse<RES> beforeExecute(REQ req, CONTEXT context)  {
        return ServiceResponse.success();
    }

    /**
     * 后置执行
     *
     * @param req
     * @param context
     */
    protected ServiceResponse<RES> afterExecute(ServiceResponse<RES> res, REQ req, CONTEXT context) {
        return res;
    }

    public void addPlot(IPlot filter) {
        this.plots.add(filter);
    }

    /**
     * 自定义执行步骤编排
     *
     * @return
     */
    protected ServiceResponse<List<IPlot>> changePlotChain(REQ req, CONTEXT context) {
        return ServiceResponse.success(this.plots);
    }

    /**
     * Context初始化
     *
     * @param req
     * @return
     */
    protected abstract CONTEXT initContext(REQ req);

    public List<IPlot> getPlot() {
        return this.plots;
    }
}

注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Function {
    /**
     * 功能名称
     *
     * @return
     */
    String name();

    /**
     * 功能描述
     *
     * @return
     */
    String desc() default "";

    /**
     * 功能下的子功能
     *
     * @return
     */
    Class<? extends IPlot>[] plots();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Plot {
    /**
     * 子功能名称
     *
     * @return
     */
    String name();
    /**
     * 描述
     *
     * @return
     */
    String desc() default "";
    /**
     * 标识码
     *
     * @return
     */
    String code() default "";
}

测试类

@Function(
        name = "测试编排方法",
        desc = "执行完步骤A,执行步骤B",
        plots ={PlotA.class, PlotB.class}
)
@Component
public class FunctionA extends IFunction<BaseContext,Integer, Context> {

   //初始化上下文
    @Override
    protected  BaseContext initContext(Integer o) {
        return new BaseContext();
    }
   //后置处理
    @Override
    protected ServiceResponse<BaseContext> afterExecute(ServiceResponse<BaseContext> res, Integer req, BaseContext context) {
        return res;
    }
}
@Plot(
     name ="测试执行步骤A",
     desc = "调用handlerA处理数据"
)
@Component
public class PlotA implements IPlot<BaseContext,Integer, BaseContext> {
    @Autowired
    Handler handlerA;
    @Override
    public ServiceResponse<BaseContext> execute(Integer res, BaseContext baseContext) throws Exception {
      ServiceResponse().success(handlerA.execute(res));
    }
}
@Plot(
     name ="测试执行步骤B",
     desc = "调用handlerB处理数据"
)
@Component
public class PlotA implements IPlot<BaseContext,Integer, BaseContext> {
    @Autowired
    Handler handlerB;
    @Override
    public ServiceResponse<BaseContext> execute(Integer res, BaseContext baseContext) throws Exception {
      ServiceResponse().success(handlerB.execute(res));
    }

}