purpose
Through a custom filter, when the dubbo interface is called, the input parameter information, request interface name and return value information are printed, which can avoid manually printing the input parameter log requested by the interface in each interface, and realize a unified log printing method There are many, here is just to learn custom filters, so take this as an example
application
To implement a custom filter, the following steps are required
1. Custom filter implementation class
@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. Configure filter
The directory here can’t be wrong, and it must be like
this
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
This error was reported. Finally, according to the blog of this classmate who failed to start dubbo , I found out that there was a problem with the META-INF.dubbo.internal directory.
Dubbo specifies three paths to set up custom filters. When dubbo is started, it will load filter information from these three directories. They are:
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. Make filter take effect
There are three ways:
1. Customize the filter above, add the @Activate(group = "provider" annotation to the filter implementation class, and specify whether the service provider or the consumer is valid
. 2. If you do not set this annotation, you can use the annotation of the service provider Set the filter attribute
in the xml configuration file. In the xml configuration file, set the filter
<dubbo:provider filter=”"/> or <dubbo:consumer filter=""/> to configure the filter to be used through the filter. This is for all Service provider or service consumer
4. Service Provider Code
@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. Effect
打印日志:interface:ProviderService;methodName:getOrderById;argument:[Ljava.lang.Object;@47a504d4
orderId是:1
打印返回结果
Order{
orderId=1, orderType='testOrderType', orderName='testOrderName'}
In this case, the filter mechanism can be used to uniformly print the log when the dubbo service is called. There is no need to record the log every time the dubbo interface is added.
Similarly, you can also customize the filter to handle exceptions in a unified manner, etc.