表示一个扩展是否被激活(使用),可以放在类定义和方法上,

dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机。

 先看下定义:

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

它有两个设置过滤条件的字段,group,value 都是字符数组。

 用来指定这个扩展类在什么条件下激活。

 下面以com.alibaba.dubbo.rpc.filter接口的几个扩展来说明。

//如MonitorFilter
@Activate(group = {Constants.PROVIDER, Constants.CONSUMER})
public class MonitorFilter implements Filter {

}
//表示如果过滤器使用方(通过group指定)属于Constants.PROVIDER(服务提供方)或者Constants.CONSUMER(服务消费方)就激活使用这个过滤器
//再看这个扩展
@Activate(group = Constants.PROVIDER, value = Constants.TOKEN_KEY)
public class TokenFilter implements Filter {

}
//表示如果过滤器使用方(通过group指定)属于Constants.PROVIDER(服务提供方)并且 URL中有参数 Constants.TOKEN_KEY(token)时就激活使用这个过滤器

 再看下具体实现:

dubbo在ExtensionLoader类,解析某个接口扩展实现类时,会把所有实现类中有Activate注解的,都先放到一个全局map中。

Activate activate = clazz.getAnnotation(Activate.class);
if (activate != null) {
    //如果有,加入,cachedActivates map 扩展名:实现类class,形式
    cachedActivates.put(names[0], activate);
}

然后提供了4个方法来具体使用cachedActivates,返回要激活使用的扩展。

1 /**
  2  * Dubbo使用的扩展点获取。<p>
  3  * <ul>
  4  * <li>自动注入关联扩展点。</li>
  5  * <li>自动Wrap上扩展点的Wrap类。</li>
  6  * <li>缺省获得的的扩展点是一个Adaptive Instance。
  7  * </ul>
  8  */
  9 public class ExtensionLoader<T> 类中有如下四个方法
 10 
 11 /**
 12      * This is equivalent to <pre>
 13      *     getActivateExtension(url, key, null);
 14      * </pre>
 15      * 在所有的激活中,要使用key 指定的扩展
 16      * @param url url
 17      * @param key url parameter key which used to get extension point names
 18      * @return extension list which are activated.
 19      * @see #getActivateExtension(com.alibaba.dubbo.common.URL, String, String)
 20      */
 21     public List<T> getActivateExtension(URL url, String key)
 22 
 23       /**
 24      * This is equivalent to <pre>
 25      *     getActivateExtension(url, url.getParameter(key).split(","), null);
 26      * </pre>
 27      * 在所有的激活中,要指定的group 外加 使用key 指定的扩展
 28      * @param url   url
 29      * @param key   url parameter key which used to get extension point names
 30      * @param group group
 31      * @return extension list which are activated.
 32      * @see #getActivateExtension(com.alibaba.dubbo.common.URL, String[], String)
 33      */
 34     public List<T> getActivateExtension(URL url, String key, String group)
 35 
 36       /**
 37      * This is equivalent to <pre>
 38      *     getActivateExtension(url, values, null);
 39      * </pre>
 40      * 在所有的激活中 values指定的扩展
 41      * @param url    url
 42      * @param values extension point names
 43      * @return extension list which are activated
 44      * @see #getActivateExtension(com.alibaba.dubbo.common.URL, String[], String)
 45      */
 46     public List<T> getActivateExtension(URL url, String[] values)
 47 
 48     //最后其实都有下面方法实现
 49        /**
 50      * Get activate extensions.
 51      * 加载active扩展
 52      * @param url    url
 53      * @param values extension point names
 54      * @param group  group
 55      * @return extension list which are activated
 56      * @see com.alibaba.dubbo.common.extension.Activate
 57      */
 58     public List<T> getActivateExtension(URL url, String[] values, String group) {
 59         List<T> exts = new ArrayList<T>();
 60         List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values);
 61         if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {
 62             getExtensionClasses();
 63             //cachedActivates里放的map结构 接口实现扩展名:其上的Activate对象
 64             for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {//遍历所有Activate注解对象
 65                 String name = entry.getKey();//spi 扩展名
 66                 Activate activate = entry.getValue();
 67                 if (isMatchGroup(group, activate.group())) {//如果有group匹配
 68                     T ext = getExtension(name);//加在扩展类
 69                     //name不在 values 指定之列,并且没排除name,并且activate的value 在url有对应参数,就算激活
 70                     if (!names.contains(name)
 71                             && !names.contains(Constants.REMOVE_VALUE_PREFIX + name)
 72                             && isActive(activate, url)) {
 73                         //
 74                         exts.add(ext);
 75                     }
 76                 }
 77             }
 78             //排序Activate 具体实现在ActivateComparator里,实现了Comparator 接口compare方法
 79             Collections.sort(exts, ActivateComparator.COMPARATOR);
 80         }
 81         List<T> usrs = new ArrayList<T>();
 82         for (int i = 0; i < names.size(); i++) {
 83             String name = names.get(i);
 84             if (!name.startsWith(Constants.REMOVE_VALUE_PREFIX)
 85                     && !names.contains(Constants.REMOVE_VALUE_PREFIX + name)) {
 86                 //遍历所有没有排除的扩展名
 87                 if (Constants.DEFAULT_KEY.equals(name)) {
 88                     if (usrs.size() > 0) {
 89                         exts.addAll(0, usrs);
 90                         usrs.clear();
 91                     }
 92                 } else {
 93                     //通过扩展名,加载扩展添加到结果集
 94                     T ext = getExtension(name);
 95                     usrs.add(ext);
 96                 }
 97             }
 98         }
 99         if (usrs.size() > 0) {
100             exts.addAll(usrs);
101         }
102     //返回符合条件的激活扩展
103         return exts;
104     }