(八)过滤器-Filter

序前

dubbo会扫描META-INF/dubbo/internal/,META-INF/dubbo/,META-INF/services/目录下的文件,

比如,过滤器的扩展类,则会扫描com.alibaba.dubbo.rpc.Filter文件的扩展类,如该文件的内容:

afterFilter=lam.dubbo.provider.filter.AfterFilter
beforeFilter=lam.dubbo.provider.filter.BeforeFilter


dubbo扫描扩展类,会先扫描本应用的resources下的文件,然后接着会扫描应用依赖的jar包里的文件。

 

 

 

源码

下面看看dubbo是如果实现过滤器的,在com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper源码中,如下。
 

//暴露服务时,创建过虑器链子
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
    if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
        return protocol.export(invoker);
    }
    return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
}

 

//引用服务时,创建过虑器链子
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
    if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
        return protocol.refer(type, url);
    }
    return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);
}

 

//这里使用了责任链模式
private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
    Invoker<T> last = invoker;
    List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
    if (filters.size() > 0) {
        for (int i = filters.size() - 1; i >= 0; i --) {
            final Filter filter = filters.get(i);
            final Invoker<T> next = last;
            last = new Invoker<T>() {

                public Class<T> getInterface() {
                    return invoker.getInterface();
                }

                public URL getUrl() {
                    return invoker.getUrl();
                }

                public boolean isAvailable() {
                    return invoker.isAvailable();
                }

                public Result invoke(Invocation invocation) throws RpcException {
                    return filter.invoke(next, invocation);
                }

                public void destroy() {
                    invoker.destroy();
                }

                @Override
                public String toString() {
                    return invoker.toString();
                }
            };
        }
    }
    return last;
}

 

实现

 

下面看看自定义的几个过虑器扩展类

@Activate(group = {Constants.PROVIDER}, value = "beforeFilter")
public class BeforeFilter implements Filter{

    public BeforeFilter(){
        System.out.println(getClass().getName() + " constructor");
    }
    
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        System.out.println(String.format("%s.%s(%s) before.",
                invocation.getClass().getName(), invocation.getMethodName(), invocation.getParameterTypes()));
        return invoker.invoke(invocation);
    }

}

 

 

 

@Activate(group = {Constants.PROVIDER}, value = "afterFilter")
public class AfterFilter implements Filter{
    
    public AfterFilter(){
        System.out.println(getClass().getName() + " constructor");
    }

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Result result = invoker.invoke(invocation);
        System.out.println(String.format("%s.%s(%s) after.",
                        invocation.getClass().getName(), invocation.getMethodName(), invocation.getParameterTypes()));
        return result;
    }

}

 

在dubbo的配置文件再配置上过滤器的标签
<dubbo:provider filter="beforeFilter,afterFilter"/>
可以指定到provider,service标签,不过group要匹配提供者,或者无条件。
可以指定到consumer,reference标签,不过group要匹配消费者,或者无条件。
group也可以同时指定provider和consumer
com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.login([Ljava.lang.Class;@3c8d3e36) before.
07-07 11:50:47:INFO(22) lam.dubbo.provider.api.impl.LoginServiceImpl - login - args:user_0
com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.login([Ljava.lang.Class;@3c8d3e36) after.

<dubbo:provider filter="beforeFilter"/>
com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.login([Ljava.lang.Class;@6d95b191) before.
07-07 11:56:59:INFO(22) lam.dubbo.provider.api.impl.LoginServiceImpl - login - args:user_0

自己写了个RPC:

https://github.com/nytta

可以给个star,^0^.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值