拦截器
说明
有时候我们需要统计方法的耗时,需要知道统计出参/入参的相关信息。
通过拦截器都可以非常方便的实现。
设计思路
无论是客户端还是服务端,只需要在方法执行前后,加入拦截器相关的方法调用,加入对应的上下文信息即可。
客户端实现
个人理解
目前主要在客户端添加拦截器,其实服务端是类似的。
接口
public interface Interceptor {
/**
* 开始
* @param context 上下文
* @since 0.1.4
*/
void before(final InterceptorContext context);
/**
* 结束
* @param context 上下文
* @since 0.1.4
*/
void after(final InterceptorContext context);
/**
* 异常处理
* @param context 上下文
* @since 0.1.4
*/
void exception(final InterceptorContext context);
}
实现
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 状态判断
//...
//1. 拦截器
final Interceptor interceptor = proxyContext.interceptor();
final InterceptorContext interceptorContext = DefaultInterceptorContext.newInstance()
.traceId(traceId);
interceptor.before(interceptorContext);
// 构建基本调用参数
//...
//proxyContext 中应该是属于当前 service 的对应信息。
// 每一次调用,对应的 invoke 信息应该是不通的,需要创建新的对象去传递信息
// rpcRequest 因为要涉及到网络间传输,尽可能保证其简洁性。
//...
//3. 执行远程调用
//...
interceptor.after(interceptorContext);
return result;
}
本期为了简单,暂时没有处理异常相关的拦截处理。
测试代码
register
启动
server
启动
client
- 测试代码
客户端配置指定耗时拦截器。
config.interceptor(new CostTimeInterceptor());
- 日志
[INFO] [2019-11-01 23:26:10.337] [main] [c.g.h.r.c.s.i.i.CostTimeInterceptor.after] - [Interceptor] cost time 49 mills for traceId: 6de5c8da8c784801921a2d2887f6e543