Dubbo的很多功能諸如泛化調用都是基於Filter機制實現。
項目中,我們可以自定義一個Filter來實現我們的業務需求,比如記錄入參出參,規範返回參數,併發控制,隱式傳輸數據等都可以基於Filter機制實現
Dubbo默認的Filter在META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Filter文件中定義
如何自定義一個Dubbo Filter
1、我們先需要定義一個類來實現com.alibaba.dubbo.rpc.Filter該接口
2、然後定義一個文件工程目錄下/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter配置該接口,以key-value形式保存,該文件會被ExtensionLoader去加載初始化
3、上面的文件key在provider和cunsumer配置文件裡定義即可
@SPI
public interface Filter {
Result invoke(Invoker> invoker, Invocation invocation) throws RpcException;
}
第一個參數invoker是接口實現類
第二個參數invocation是方法名和參數
Result是返回結果類
RpcException是封裝的異常
Filter實現接口入參出參日誌
1、實現com.alibaba.dubbo.rpc.Filter
public class DubboLogFilter implements Filter {
private final static Logger logger = LoggerFactory.getLogger(DubboLogFilter.class);
@Override
public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {
String name = invoker.getInterface().getName();
Object[] args = invocation.getArguments();
String method = invocation.getMethodName();
String prefix = "logger:" + name + "." + method;
logger.info(prefix + " in param =>" + JSONArray.toJSONString(args));
Result r = invoker.invoke(invocation);
if (r.hasException()) {
Throwable e = r.getException();
logger.error(prefix+" error =>"+JSONObject.toJSONString(e.getMessage()));
} else {
logger.info(prefix + " out result =>" + JSONObject.toJSONString(r));
}
return r;
}
}
2、配置filter到META-INF中
/src/main/resources/META-INF/dubbo/下新建文件:com.alibaba.dubbo.rpc.Filter
文件內容如下:
interfaceLogFilter=com.fangtb.filter.DubboLogFilter
3、在provider和cunsumer配置文件裡定義
<provider>
<consumer>
如果覺得第三步覺得繁瑣,可以該Filter實現類定義成全局的,可以使用@Activate將該Filter定義為全局的Filter
在實現類添加註解
@Activate( group = {Constants.PROVIDER, Constants.CONSUMER}, order = -1000)
public class DubboLogFilter implements Filter {}
Activate註解表示一個擴展是否被激活(使用),可以放在類定義和方法上,dubbo用它在spi擴展類定義上,表示這個擴展實現激活條件和時機。group,value 都是字符數組。用來指定這個擴展類在什麼條件下激活,order越小,優先級越高。
通過group指定屬於Constants.PROVIDER(服務提供方)或者Constants.CONSUMER(服務消費方)就激活使用這個過濾器。
閱讀更多 GT七妖妖 的文章