dubbo @Activate 注解使用和實現解析


 Activate注解表示一個擴展是否被激活(使用),可以放在類定義和方法上

           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 }
View Code

 

它有兩個設置過濾條件的字段,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     }
View Code

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM