带你读《2022技术人的百宝黑皮书》——一种可灰度的接口迁移方案(2)https://developer.aliyun.com/article/1339610?groupCode=taobaotech
接口代理
接口代理主要通过切面来拦截,通过注解方法的方式来实现。代理注解如下
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface EnableProxy { // 用于标识代理类Class<?> proxyClass(); // 用于标识转发的代理类的方法,默认取目标类的方法名 String methodName() default ""; // 对于单条数据的查询,可以指定key的参数索引位置,会解析后转 int keyIndex() default -1; ]
切面的实现核心逻辑就是拦截注解,根据代理分发的逻辑去判断是否走代理类,如果走代理类需要解析代理类型、方法名、参数,然后进行转发。
////
@Component @Aspect @Slf4j public class ProxyAspect { // 核心代理类@Resource private ProxyManager proxyManager; // 注解拦截@Pointcut("@annotation(***)") private void proxy() {} @Around("proxy()") @SuppressWarnings("rawtypes") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { try { MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); Class<?> clazz = joinPoint.getTarget().getClass(); String methodName = methodSignature.getMethod().getName(); Class[] parameterTypes = methodSignature.getParameterTypes(); Object[] args = joinPoint.getArgs(); // 拿到方法的注解 EnableProxy enableProxyAnnotation = ReflectUtils .getMethodAnnotation(clazz, EnableProxy.class, methodName, parameterTypes); 26 if (enableProxyAnnotation == null) { // 没有找到注解,直接放过 return joinPoint.proceed(); } //判断是否需要走代理 Boolean enableProxy = enableProxy(clazz, methodName, args, enableProxyAnnotation); if (!enableProxy) { // 不开启代理,直接放过 return joinPoint.proceed(); } // 默认取目标类的方法名称 methodName = StringUtils.isNotBlank(enableProxyAnnotation.methodName()) ? enableProxyAnnotation.methodName() : methodName; // 通过反射拿到代理类的代理方法 Object bean = ApplicationContextUtil.getBean(enableProxyAnnotation.proxyClass()); Method proxyMethod = ReflectUtils.getMethod(enableProxyAnnotation.proxyClass(), method- Name, parameterTypes); if (bean == null || proxyMethod == null) { // 没有代理类或代理方法,直接走原逻辑 return joinPoint.proceed(); } // 通过反射,转发代理类方法 return ReflectUtils.invoke(bean, proxyMethod, joinPoint.getArgs()); } catch (BizException bizException) { // 业务方法异常,直接抛出 throw bizException; } catch (Throwable throwable) { // 其他异常,打个日志感知一下 throw throwable; } } }
带你读《2022技术人的百宝黑皮书》——一种可灰度的接口迁移方案(4)https://developer.aliyun.com/article/1339608?groupCode=taobaotech