dubbo 自定义filter

目的

通过自定义filter,在dubbo接口被调用的时候,打印入参信息、请求接口名称和返回值信息,这样可以避免在每个接口中手动打印接口请求的入参等日志,实现统一打印日志的方式有多种,这里只是为了学习自定义filter,所以以这个为例

应用

要实现自定义filter,需要有以下几个步骤

1.自定义filter实现类

@Activate(group = "provider")
public class DubboProviderLogFilter implements Filter {
    
    
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
    
    
        System.out.println(
                "打印日志:interface:" + invoker.getInterface().getSimpleName() + ";methodName:" + invocation.getMethodName()
                        + ";argument:" + invocation.getArguments());
        Result result = invoker.invoke(invocation);
        System.out.println("打印返回结果");
        System.out.println(result != null ? result.getValue() : "返回结果为空");
        return result;
    }
}

2.配置filter

在这里插入图片描述

这里的目录不能错,并且必须是这种样子的
在这里插入图片描述
这里踩了一个坑,在启动的时候,一直提示

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'providers:dubbo:xxx': Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'filter' threw exception; nested exception is java.lang.IllegalStateException: No such extension requestFilter for filter/com.alibaba.dubbo.rpc.Filter
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1650)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1357)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
	at 
Caused by: org.springframework.beans.PropertyBatchUpdateException: Failed properties: Property 'filter' threw exception; nested exception is java.lang.IllegalStateException: No such extension requestFilter for filter/com.alibaba.dubbo.rpc.Filter
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:123)
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:77)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1646)
	... 16 common frames omitted

这个报错,最后,根据 dubbo启动失败 这个同学的博客,才发现,原来是META-INF.dubbo.internal的目录有问题

dubbo指定了三个路径可以设置自定义filter,dubbo在启动的时候,会从这三个目录下去加载filter信息,分别是:

loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY);
loadDirectory(extensionClasses, DUBBO_DIRECTORY);
loadDirectory(extensionClasses, SERVICES_DIRECTORY);

private static final String SERVICES_DIRECTORY = "META-INF/services/";

private static final String DUBBO_DIRECTORY = "META-INF/dubbo/";

private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + "internal/";

3.使filter生效

有三种方式
1.上面自定义filter,在filter实现类添加@Activate(group = “provider"注解,并指定服务提供者还是消费者端生效
2.如果不设置该注解,可以在服务提供者的注解中设置filter属性
在这里插入图片描述
3.在xml配置文件中,统一设置filter
<dubbo:provider filter=”"/>或<dubbo:consumer filter=""/> 通过filter来配置要使用的filter,这种是针对所有的服务提供者或者服务消费者

4. 服务提供者代码

@Service(timeout = 3500)
public class ProviderServiceImpl implements ProviderService {
    
    
    @Override
    public Order getOrderById(Integer orderId) {
    
    
        System.out.println("orderId是:" + orderId);
        Order order = new Order(1, "testOrderType", "testOrderName");
        return order;
    }
}

5.效果

打印日志:interface:ProviderService;methodName:getOrderById;argument:[Ljava.lang.Object;@47a504d4
orderId是:1
打印返回结果
Order{
    
    orderId=1, orderType='testOrderType', orderName='testOrderName'}

这样的话,就可以通过filter机制,在dubbo服务调用的时候,统一打印日志,无需在每次新增dubbo接口的时候,记录日志
同理,也可以自定义filter,统一对异常进行处理 等等

猜你喜欢

转载自blog.csdn.net/CPLASF_/article/details/111227606