Dubbo的filter按需加载

背景

一天之内 两个小伙伴问我关于filter的按需加载的机制 有必要这边记录一下

关于filter的说明

dubbo源码系列之filter的前生

dubbo源码系列之filter的今世

分析

关于dubbo中Activate的注解中存在如下几个属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Activate {
/**
* Group过滤条件。
* <br />
* 包含{@link ExtensionLoader#getActivateExtension}的group参数给的值,则返回扩展。
* <br />
* 如没有Group设置,则不过滤。
*/
String[] group() default {};
/**
* Key过滤条件。包含{@link ExtensionLoader#getActivateExtension}的URL的参数Key中有,则返回扩展。
* <p />
* 示例:<br/>
* 注解的值 <code>@Activate("cache,validatioin")</code>,
* 则{@link ExtensionLoader#getActivateExtension}的URL的参数有<code>cache</code>Key,或是<code>validatioin</code>则返回扩展。
* <br/>
* 如没有设置,则不过滤。
*/
String[] value() default {};
/**
* 排序信息,可以不提供。
*/
String[] before() default {};
/**
* 排序信息,可以不提供。
*/
String[] after() default {};
/**
* 排序信息,可以不提供。
*/
int order() default 0;
}

其中 before,after,order可以用来调整filter的顺序

而group用来描述生效的side【provider,consumer】

1
2
3
public static final String PROVIDER = "provider";
public static final String CONSUMER = "consumer";

那么还剩下一个关键的属性value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private boolean isActive(Activate activate, URL url) {
String[] keys = activate.value();
if (keys == null || keys.length == 0) {
return true;
}
for (String key : keys) {
for (Map.Entry<String, String> entry : url.getParameters().entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
if ((k.equals(key) || k.endsWith("." + key))
&& ConfigUtils.isNotEmpty(v)) {
return true;
}
}
}
return false;
}

可以看出当value为空或者size为0那么此时isActive就返回true 也就是说filter将会生效。

那么当url中参数包含对应的value的值或者以.XXX【XXX为对应的参数值】也将生效

其他场景也就是isActivate返回false 将不会生效~

那么如何设置对应的filter的参数呢???

1
2
3
4
5
6
7
8
9
10
11
12
protected <T> ServiceBean<T> registerService(RegistryConfig registryConfig, ApplicationConfig applicationConfig, ProviderConfig providerConfig, ProtocolConfig protocolConfig, Dubbo dubbo, Class<T> interfaceClazz, T t) {
ServiceBean<T> ref = new ServiceBean<>();
ref.setInterface(interfaceClazz);
ref.setRegistry(registryConfig);
ref.setApplication(applicationConfig);
ref.setProvider(providerConfig);
ref.setRef(t);
ref.setProtocol(protocolConfig);
ref.setGroup(dubbo.getGroup());
ref.setFilter("clientProvider");
return ref;
}

filter可以增加参数了~