As we have seen above, Dubbo introduces a filter chain mechanism to wrap (or extend) functionality in service invocation or consumer sending request commands. Many of Dubbo’s functions, such as generalized calls and concurrency control, are based on the Filter mechanism. System default Filter in/dubbo xml-rpc API/SRC/main/resources/meta-inf/dubbo/internal/com. Alibaba. Dubbo. RPC. The Filter file definition, content is as follows:

echo=com.alibaba.dubbo.rpc.filter.EchoFilter
generic=com.alibaba.dubbo.rpc.filter.GenericFilter
genericimpl=com.alibaba.dubbo.rpc.filter.GenericImplFilter
token=com.alibaba.dubbo.rpc.filter.TokenFilter
accesslog=com.alibaba.dubbo.rpc.filter.AccessLogFilter
activelimit=com.alibaba.dubbo.rpc.filter.ActiveLimitFilter
classloader=com.alibaba.dubbo.rpc.filter.ClassLoaderFilter
context=com.alibaba.dubbo.rpc.filter.ContextFilter
consumercontext=com.alibaba.dubbo.rpc.filter.ConsumerContextFilter
exception=com.alibaba.dubbo.rpc.filter.ExceptionFilter
executelimit=com.alibaba.dubbo.rpc.filter.ExecuteLimitFilter
deprecated=com.alibaba.dubbo.rpc.filter.DeprecatedFilter
compatible=com.alibaba.dubbo.rpc.filter.CompatibleFilter
timeout=com.alibaba.dubbo.rpc.filter.TimeoutFilter
Copy the code

To illustrate the defining elements of a Filter:

/** * EchoInvokerFilter */ @Activate(group = Constants.PROVIDER, order = -110000) // @2 public class EchoFilter implements Filter { // @1 @Override public Result invoke(Invoker<? > invoker, Invocation inv) throws RpcException { if (inv.getMethodName().equals(Constants.$ECHO) && inv.getArguments() ! = null && inv.getArguments().length == 1) return new RpcResult(inv.getArguments()[0]); return invoker.invoke(inv); }}Copy the code

Code @ 1: implement com. Alibaba. Dubbo. RPC. The Filter interface. @2: add Activate, annotated with the following meanings: group: group, String[], such as the consumer, server. Value String[], if specified, the filter is active only if the consumer or service provider URL contains a key-value pair with the attribute name value. Before: String[], which specifies the execution order, before the specified filter is executed before the filter. After: string[], which specifies the order in which the filter specified after is executed. Order: the order specified by the user. The smaller the value, the earlier the execution. In addition to the default Filter, Dubbo also supports custom filters. You can specify filters by using service. Filter. Multiple filters are separated by commas (,). > < dubbo:parameter key = “service.filter” value = “filter1,filer2…” /> < /dubbo:service> Of course, you can set a common filter for all service providers by specifying it as < dubbo:provider… > < dubbo:parameter key = “service.filter” value = “filter1,filer2…” /> < /dubbo:provider> The key of a custom filter on the consumer side is reference.filter, which can be used to define attributes under the < dubbo:reference/> tag or the < dubbo:consumer/> tag. The code for parsing a custom Filter is as follows: ExtensionLoader#getActivateExtension

public List<T> getActivateExtension(URL url, String key, String group) { // @1 String value = url.getParameter(key); // @2 return getActivateExtension(url, value == null || value.length() == 0 ? null : Constants.COMMA_SPLIT_PATTERN.split(value), group); / / @ 3}Copy the code

Code @1: Parameter description. URL URL: SERVICE provider or service consumer URL. String key: indicates the key of the filter property. The value of the service provider is service.filter, and that of the service consumer is reference.filter. String Group: Service provider or service consumer. Code @2: Get the configured custom filter from the URL. Code @3: If value is not empty, the string is converted to an array with a call to split, and then the getActivateExtension method is called to get the filter that meets the criteria. ExtensionLoader#getActivateExtension

public List<T> getActivateExtension(URL url, String[] values, String group) { List<T> exts = new ArrayList<T>(); List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values); if (! names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) { // @1 getExtensionClasses(); // @2 for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) { String name = entry.getKey(); Activate activate = entry.getValue(); if (isMatchGroup(group, activate.group())) { // @3 T ext = getExtension(name); if (! names.contains(name) && ! names.contains(Constants.REMOVE_VALUE_PREFIX + name) // @4 && isActive(activate, url)) { // @5 exts.add(ext); } } } Collections.sort(exts, ActivateComparator.COMPARATOR); } List<T> usrs = new ArrayList<T>(); for (int i = 0; i < names.size(); i++) { // @6 String name = names.get(i); if (! name.startsWith(Constants.REMOVE_VALUE_PREFIX) && ! names.contains(Constants.REMOVE_VALUE_PREFIX + name)) { if (Constants.DEFAULT_KEY.equals(name)) { if (! usrs.isEmpty()) { exts.addAll(0, usrs); usrs.clear(); } } else { T ext = getExtension(name); usrs.add(ext); } } } if (! usrs.isEmpty()) { exts.addAll(usrs); } return exts; }Copy the code

@1: If the configured service.filter or refereccE. Filter contains -default, it disables a set of filters provided by the system by default. Code @2: If the system default filter chain is disabled, all default filters are loaded first. Code @3: Select the appropriate filter according to the group brush. @4: It is also possible to disable a single filter by -filter name. For example, to disable AccessLogFilter, run the -accesslog command. – the key, the key to/dubbo xml-rpc API/SRC/main/resources/meta-inf/dubbo/internal/com. Alibaba. Dubbo. R PC. The Filter is defined in the key. Code @5: Check whether the Filter is activated. The logic is that if the @activate annotation value on the Filter is not empty, the URL needs to check whether there are attribute pairs with the key value as value. @6: load a user-defined Filter, that is, the Filter specified by service. Filter or reference.filter. In summary, Dubbo provides a filter mechanism that provides extension points before the real service is invoked. The Filter mechanism is briefly introduced here, and the core Filter provided by Dubbo service will be analyzed from the following. If you need to set the Filter, the need to determine the engineering of the meta-inf/dubbo/internal/com. Alibaba. The dubbo. RPC. Registered in the Filter files. That’s all for this article. From the beginning of the next part, the implementation process will be analyzed in detail according to the functional characteristics of Dubbo, which are essentially a variety of Dubbo filters.


Welcome to add the author micro signal (DINGwPMZ), add group discussion, the author quality column catalog: 1, source analysis RocketMQ column (40 +) 2, source analysis Sentinel column (12 +) 3, source analysis Dubbo column (28 +) 4, source analysis Mybatis column 5, source analysis Netty column (18 +) 6, source analysis JUC column Source code analysis (MyCat) for Elasticjob