通过反射实现方法调用的统一转发

标题通过 反射实现方法调用的统一转发

目的:当请求到来时,通过切面和注解的方式 将方法的调用目的地转发到目标方法:

//此为转发调用的核心方法
@Service
@Transactional(rollbackFor = Exception.class)
public class ControlCenterApiServiceImpl implements ControlCenterApiService {
	//doLog为记录日志的,可以不用关注
    @Override
    public Object invoke(ControlCenterRequest request) {
        String uri = request.getUri();
        String clazzUri = uri.substring(0, uri.lastIndexOf(":"));
        String methodUri = uri.substring(uri.lastIndexOf(":") + 1);
        Object invoke = null;
        Set<Map.Entry<String, Object>> entries = SpringUtils.getContext().getBeansWithAnnotation(CenterUri.class).entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            Object value2 = entry.getValue();
            Class<?> aClass = value2.getClass();
            Class<?> userClass = ClassUtils.getUserClass(aClass);
            CenterUri annotation = userClass.getAnnotation(CenterUri.class);
            String value = annotation.value();
            if (value.equals(clazzUri)) {
                Method[] declaredMethods = userClass.getDeclaredMethods();
                for (Method method : declaredMethods) {
                    if (method.isAnnotationPresent(CenterUri.class)) {
                        CenterUri methodAn = method.getAnnotation(CenterUri.class);
                        if (ObjectUtils.isEmpty(methodAn)) {
                            continue;
                        }
                        String value1 = methodAn.value();
                        if (value1.equals(methodUri)) {
                            long start = System.currentTimeMillis();
                            try {
                                Object executeTarget = SpringUtils.getBeanByType(Class.forName(userClass.getName()));
//                                executeTarget = userClass.getConstructor().newInstance();
                                invoke = method.invoke(executeTarget, request);
                                long end = System.currentTimeMillis();
                                Long consuming = end - start;
                                doLog(request, JsonUtils.toJson(invoke), true, true, 0, method.getName(), consuming);
                                return invoke;
                            } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | RuntimeException e) { //NoSuchMethodException | InstantiationException |
                                long end = System.currentTimeMillis();
                                Long consuming = end - start;
                                doLog(request, JsonUtils.toJson(invoke), false, false, 0, method.getName(), consuming);
                                throw new BizException(ControlCenterErrorEnum.INTERFACE_INVOKE_ERROR, ControlCenterErrorEnum.INTERFACE_INVOKE_ERROR.getDesc());
                            }
                        }
                    }
                }
            }
        }
        ObjectResult<Object> responseData = new ObjectResult<>();
        responseData.setSuccess(false);
        responseData.setMessage(request.getUri() + "请求失败");
        return responseData;
    }
//此注解类似于我们使用到的postMapping注解和GetMapping注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CenterUri {

    String value();
}

CenterUri 的使用方式如下:

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@CenterUri("mom")
public class MomApiServiceImpl implements MomApiService {
@Override
@CenterUri("submitEqptAlive")
public ObjectResult submitEqptAlive(ControlCenterRequest request)

理论输出:
当我们在调用由@CenterUri注解标注的类中的方法时,invoke会根据方类和方法上的注解的value值来判定要请求的方法时哪个,并将参数转发至要调用的方法形参中;然后执行上面的invoke方法来实现方法的转发调用

调用方式:

  @Override
    public ObjectResult wmsCommitInventoryStatusToErpRequest(List<CommitInventoryStatusDetailRequest> data) {
        Map<String, Object> ccapiParam = new HashMap<>();
        ControlCenterRequest ccapiRequest = new ControlCenterRequest();
        ccapiRequest.setHouseCode(LesConfig.houseCode);
        ccapiRequest.setSystemCode(LesConfig.systemCode);
        ccapiRequest.setParams(ccapiParam);
        ccapiRequest.setUri("erp:inventoryStatus");
        ObjectResult ccapiResponse = (ObjectResult) controlCenterApiService.invoke(ccapiRequest);

        return ccapiResponse;
    }

以上代码只通过invoke的调用即可请求到目标执行方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

86822

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值