如何将 Dubbo Filter 拦截器原理运用到日志拦截器中?

业务背景

我们希望可以在使用日志拦截器时,定义属于自己的拦截器方法。

实现的方式有很多种,我们分别来看一下。

v1-基本版本

接口

最常见的定义方式,在方法执行前后,异常,finally 提供钩子函数。

package com.github.houbb.auto.log.api;
/**
 * autoLog 拦截器
 * @author binbin.hou
 * @since 0.0.10
 */
public interface IAutoLogInterceptor {
    /**
     * 执行之前
     * @param interceptorContext 拦截器上下文
     * @since 0.0.10
     */
    void beforeHandle(IAutoLogInterceptorContext interceptorContext);
    /**
     * 执行之后
     * @param interceptorContext 拦截器上下文
     * @param result 方法执行结果
     * @since 0.0.10
     */
    void afterHandle(IAutoLogInterceptorContext interceptorContext,
                     final Object result);
    /**
     * 异常处理
     * @param interceptorContext 拦截器上下文
     * @param exception 异常
     * @since 0.0.10
     */
    void exceptionHandle(IAutoLogInterceptorContext interceptorContext, Exception exception);
    /**
     * finally 中执行的代码
     * @param interceptorContext 拦截器上下文
     * @since 0.0.10
     */
    void finallyHandle(IAutoLogInterceptorContext interceptorContext);
}

工具中统一使用拦截器

package com.github.houbb.auto.log.core.core.impl;
/**
 * @author binbin.hou
 * @since 0.0.7
 */
public class SimpleAutoLog implements IAutoLog {
    /**
     * 自动日志输出
     *
     * @param context 上下文
     * @return 结果
     * @since 0.0.7
     */
    @Override
    public Object autoLog(IAutoLogContext context) throws Throwable {
        //1. 日志唯一标识
        // ... 省略
        List autoLogInterceptors = null;
        try {
            // ... 省略其他逻辑
            // 获取拦截器
            autoLogInterceptors = autoLogInterceptors(autoLog);

            //1.2 autoLog
            if(CollectionUtil.isNotEmpty(autoLogInterceptors)) {
                for(IAutoLogInterceptor interceptor : autoLogInterceptors) {
                    interceptor.beforeHandle(autoLogContext);
                }
            }
            //2. 执行结果
            Object result = context.process();

            //2.1 方法执行后
            if(CollectionUtil.isNotEmpty(autoLogInterceptors)) {
                for(IAutoLogInterceptor interceptor : autoLogInterceptors) {
                    interceptor.afterHandle(autoLogContext, result);
                }
            }
            //2.2 返回方法
            return result;
        } catch (Exception exception) {
            if(CollectionUtil.isNotEmpty(autoLogInterceptors)) {
                for(IAutoLogInterceptor interceptor : autoLogInterceptors) {
                    interceptor.exceptionHandle(autoLogContext, exception);
                }
            }
            throw new AutoLogRuntimeException(exception);
        } finally {
            // 先执行日志
            if(CollectionUtil.isNotEmpty(autoLogInterceptors)) {
                for(IAutoLogInterceptor interceptor : autoLogInterceptors) {
                    interceptor.finallyHandle(autoLogContext);
                }
            }
        }
    }
    /**
     * 创建拦截器列表
     * @param autoLog 注解
     * @return 结果
     * @since 0.0.10
     */
    private List autoLogInterceptors(final AutoLog autoLog) {
        List resultList = new ArrayList();
        if(ObjectUtil.isNull(autoLog)) {
            return resultList;
        }
        Class