JDK 的 SPI 思想

SPI,即 Service Provider Interface。在面向对象的设计里面,模块之间推荐基于接口编程,而不是对实现类进行硬编码,这样做也是为了模块设计的可插拔原则。

比较典型的应用,如 JDBC,Java 定义了一套 JDBC 的接口,但是 Java 本身并不提供对 JDBC 的实现类,而是开发者根据项目实际使用的数据库来选择驱动程序 jar 包,比如 mysql,你就将 mysql-jdbc-connector.jar 引入进来;oracle,你就将 oracle-jdbc-connector.jar 引入进来。在系统跑的时候,碰到你使用 jdbc 的接口,他会在底层使用你引入的那个 jar 中提供的实现类。

Dubbo 的 SPI 扩展机制原理

dubbo 自己实现了一套 SPI 机制,并对 JDK 的 SPI 进行了改进。

  1. JDK 标准的 SPI 只能通过遍历来查找扩展点和实例化,有可能导致一次性加载所有的扩展点,如果不是所有的扩展点都被用到,就会导致资源的浪费。dubbo 每个扩展点都有多种实现,例如:com.alibaba.dubbo.rpc.Protocol 接口有 InjvmProtocol、DubboProtocol、RmiProtocol、HttpProtocol、HessianProtocol 等实现,如果只是用到其中一个实现,可是加载了全部的实现,会导致资源的浪费。
  2. 对配置文件中扩展实现的格式的修改,例如,META-INF/dubbo/com.xxx.Protocol 里的 com.foo.XxxProtocol 格式 改为了 xxx = com.foo.XxxProtocol 这种以键值对的形式,这样做的目的是为了让我们更容易的定位到问题。比如,由于第三方库不存在,无法初始化,导致无法加载扩展点(“A”),当用户配置使用 A 时,dubbo 就会报无法加载扩展点的错误,而不是报哪些扩展点的实现加载失败以及错误原因,这是因为原来的配置格式没有记录扩展名的 id,导致 dubbo 无法抛出较为精准的异常,这会加大排查问题的难度。所以改成 key-value 的形式来进行配置。
  3. dubbo 的 SPI 机制增加了对 IOC、AOP 的支持,一个扩展点可以直接通过 setter 注入到其他扩展点。

下面我们看一下 Dubbo 的 SPI 扩展机制实现的结构目录。

avatar

SPI 注解

首先看一下 SPI 注解。在某个接口上加上 @SPI 注解后,表明该接口为可扩展接口。比如,协议扩展接口 Protocol,如果使用者在 <dubbo:protocol />、<dubbo:service />、<dubbo:reference /> 都没有指定 protocol 属性 的话,那么就默认使用 DubboProtocol 作为接口 Protocol 的实现,因为在 Protocol 上有 @SPI(“dubbo”)注解。而这个 protocol 属性值 或者默认值会被当作该接口的实现类中的一个 key,dubbo 会去 META-INF.dubbo.internal 下的 com.alibaba.dubbo.rpc.Protocol 文件中找该 key 对应的 value,源码如下。

  1. /**
  2. * 协议接口
  3. * Protocol 是服务域,它是 Invoker 暴露和引用的主功能入口,它负责 Invoker 的生命周期管理。
  4. */
  5. @SPI("dubbo")
  6. public interface Protocol {
  7. /**
  8. * Get default port when user doesn't config the port.
  9. */
  10. int getDefaultPort();
  11. /**
  12. * 暴露远程服务:
  13. * 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();<br>
  14. * 2. export() 必须是幂等的,也就是暴露同一个 URL 的 Invoker 两次,和暴露一次没有区别。<br>
  15. * 3. export() 传入的 Invoker 由框架实现并传入,协议不需要关心。<br>
  16. *
  17. * @param <T> 服务的类型
  18. * @param invoker 服务的执行体
  19. * @return exporter 暴露服务的引用,用于取消暴露
  20. * @throws RpcException 当暴露服务出错时抛出,比如端口已占用
  21. */
  22. @Adaptive
  23. <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
  24. /**
  25. * 引用远程服务:<br>
  26. * 1. 当用户调用 refer() 所返回的 Invoker 对象的 invoke() 方法时,协议需相应执行同 URL 远端 export() 传入的 Invoker 对象的 invoke() 方法。<br>
  27. * 2. refer() 返回的 Invoker 由协议实现,协议通常需要在此 Invoker 中发送远程请求。<br>
  28. * 3. 当 url 中有设置 check=false 时,连接失败不能抛出异常,并内部自动恢复。<br>
  29. *
  30. * @param <T> 服务的类型
  31. * @param type 服务的类型
  32. * @param url 远程服务的URL地址
  33. * @return invoker 服务的本地代理
  34. * @throws RpcException 当连接服务提供方失败时抛出
  35. */
  36. @Adaptive
  37. <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
  38. /**
  39. * 释放协议:<br>
  40. * 1. 取消该协议所有已经暴露和引用的服务。<br>
  41. * 2. 释放协议所占用的所有资源,比如连接和端口。<br>
  42. * 3. 协议在释放后,依然能暴露和引用新的服务。<br>
  43. */
  44. void destroy();
  45. }
  46. /**
  47. * 扩展点接口的标识。
  48. * 扩展点声明配置文件,格式修改。
  49. * 以Protocol示例,配置文件META-INF/dubbo/com.xxx.Protocol内容:
  50. * 由
  51. * com.foo.XxxProtocol
  52. * com.foo.YyyProtocol
  53. * 改成使用KV格式
  54. * xxx=com.foo.XxxProtocol
  55. * yyy=com.foo.YyyProtocol
  56. *
  57. * 原因:
  58. * 当扩展点的static字段或方法签名上引用了三方库,
  59. * 如果三方库不存在,会导致类初始化失败,
  60. * Extension标识Dubbo就拿不到了,异常信息就和配置信息对应不起来。
  61. *
  62. * 比如:
  63. * Extension("mina")加载失败,
  64. * 当用户配置使用mina时,就会报找不到扩展点mina,
  65. * 而不是报加载扩展点失败,等难以定位具体问题的错误。
  66. *
  67. * @author william.liangf
  68. * @author ding.lid
  69. * @export
  70. */
  71. @Documented
  72. @Retention(RetentionPolicy.RUNTIME)
  73. @Target({ElementType.TYPE})
  74. public @interface SPI {
  75. /**
  76. * default extension name
  77. *
  78. * 默认拓展名
  79. */
  80. String value() default "";
  81. }
  82. // 配置文件 com.alibaba.dubbo.rpc.Protocol 中的内容
  83. dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol

value 就是该 Protocol 接口 的实现类 DubboProtocol,这样就做到了 SPI 扩展。

ExtensionLoader

ExtensionLoader 扩展加载器,这是 dubbo 实现 SPI 扩展机制 的核心,几乎所有实现的逻辑都被封装在 ExtensionLoader 中,其源码如下。

  1. /**
  2. * 拓展加载器,Dubbo使用的扩展点获取
  3. * <ul>
  4. * <li>自动注入关联扩展点。</li>
  5. * <li>自动Wrap上扩展点的Wrap类。</li>
  6. * <li>缺省获得的的扩展点是一个Adaptive Instance。</li>
  7. * </ul>
  8. *
  9. * 另外,该类同时是 ExtensionLoader 的管理容器,例如 {@link #EXTENSION_INSTANCES} 、{@link #EXTENSION_INSTANCES} 属性。
  10. */
  11. @SuppressWarnings("deprecation")
  12. public class ExtensionLoader<T> {
  13. private static final Logger logger = LoggerFactory.getLogger(ExtensionLoader.class);
  14. private static final String SERVICES_DIRECTORY = "META-INF/services/";
  15. private static final String DUBBO_DIRECTORY = "META-INF/dubbo/";
  16. private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + "internal/";
  17. private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
  18. // ============================== 静态属性 ==============================
  19. /**
  20. * 拓展加载器集合
  21. *
  22. * key:拓展接口
  23. */
  24. private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<Class<?>, ExtensionLoader<?>>();
  25. /**
  26. * 拓展实现类集合
  27. *
  28. * key:拓展实现类
  29. * value:拓展对象。
  30. *
  31. * 例如,key 为 Class<AccessLogFilter>
  32. * value 为 AccessLogFilter 对象
  33. */
  34. private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<Class<?>, Object>();
  35. // ============================== 对象属性 ==============================
  36. /**
  37. * 拓展接口。
  38. * 例如,Protocol
  39. */
  40. private final Class<?> type;
  41. /**
  42. * 对象工厂
  43. *
  44. * 用于调用 {@link #injectExtension(Object)} 方法,向拓展对象注入依赖的属性。
  45. *
  46. * 例如,StubProxyFactoryWrapper 中有 `Protocol protocol` 属性。
  47. */
  48. private final ExtensionFactory objectFactory;
  49. /**
  50. * 缓存的拓展名与拓展类的映射。
  51. *
  52. * 和 {@link #cachedClasses} 的 KV 对调。
  53. *
  54. * 通过 {@link #loadExtensionClasses} 加载
  55. */
  56. private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<Class<?>, String>();
  57. /**
  58. * 缓存的拓展实现类集合。
  59. *
  60. * 不包含如下两种类型:
  61. * 1. 自适应拓展实现类。例如 AdaptiveExtensionFactory
  62. * 2. 带唯一参数为拓展接口的构造方法的实现类,或者说拓展 Wrapper 实现类。例如,ProtocolFilterWrapper 。
  63. * 拓展 Wrapper 实现类,会添加到 {@link #cachedWrapperClasses} 中
  64. *
  65. * 通过 {@link #loadExtensionClasses} 加载
  66. */
  67. private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<Map<String, Class<?>>>();
  68. /**
  69. * 拓展名与 @Activate 的映射
  70. *
  71. * 例如,AccessLogFilter。
  72. *
  73. * 用于 {@link #getActivateExtension(URL, String)}
  74. */
  75. private final Map<String, Activate> cachedActivates = new ConcurrentHashMap<String, Activate>();
  76. /**
  77. * 缓存的拓展对象集合
  78. *
  79. * key:拓展名
  80. * value:拓展对象
  81. *
  82. * 例如,Protocol 拓展
  83. * key:dubbo value:DubboProtocol
  84. * key:injvm value:InjvmProtocol
  85. *
  86. * 通过 {@link #loadExtensionClasses} 加载
  87. */
  88. private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<String, Holder<Object>>();
  89. /**
  90. * 缓存的自适应( Adaptive )拓展对象
  91. */
  92. private final Holder<Object> cachedAdaptiveInstance = new Holder<Object>();
  93. /**
  94. * 缓存的自适应拓展对象的类
  95. *
  96. * {@link #getAdaptiveExtensionClass()}
  97. */
  98. private volatile Class<?> cachedAdaptiveClass = null;
  99. /**
  100. * 缓存的默认拓展名
  101. *
  102. * 通过 {@link SPI} 注解获得
  103. */
  104. private String cachedDefaultName;
  105. /**
  106. * 创建 {@link #cachedAdaptiveInstance} 时发生的异常。
  107. *
  108. * 发生异常后,不再创建,参见 {@link #createAdaptiveExtension()}
  109. */
  110. private volatile Throwable createAdaptiveInstanceError;
  111. /**
  112. * 拓展 Wrapper 实现类集合
  113. *
  114. * 带唯一参数为拓展接口的构造方法的实现类
  115. *
  116. * 通过 {@link #loadExtensionClasses} 加载
  117. */
  118. private Set<Class<?>> cachedWrapperClasses;
  119. /**
  120. * 拓展名 与 加载对应拓展类发生的异常 的 映射
  121. *
  122. * key:拓展名
  123. * value:异常
  124. *
  125. * 在 {@link #loadFile(Map, String)} 时,记录
  126. */
  127. private Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<String, IllegalStateException>();
  128. private ExtensionLoader(Class<?> type) {
  129. this.type = type;
  130. objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
  131. }
  132. /**
  133. * 是否包含 @SPI 注解
  134. *
  135. * @param type 类
  136. * @param <T> 泛型
  137. * @return 是否包含
  138. */
  139. private static <T> boolean withExtensionAnnotation(Class<T> type) {
  140. return type.isAnnotationPresent(SPI.class);
  141. }
  142. /**
  143. * 根据拓展点的接口,获得拓展加载器
  144. *
  145. * @param type 接口
  146. * @param <T> 泛型
  147. * @return 加载器
  148. */
  149. @SuppressWarnings("unchecked")
  150. public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
  151. if (type == null)
  152. throw new IllegalArgumentException("Extension type == null");
  153. // 必须是接口
  154. if (!type.isInterface()) {
  155. throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
  156. }
  157. // 必须包含 @SPI 注解
  158. if (!withExtensionAnnotation(type)) {
  159. throw new IllegalArgumentException("Extension type(" + type +
  160. ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
  161. }
  162. // 获得接口对应的拓展点加载器
  163. ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
  164. if (loader == null) {
  165. EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
  166. loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
  167. }
  168. return loader;
  169. }
  170. private static ClassLoader findClassLoader() {
  171. return ExtensionLoader.class.getClassLoader();
  172. }
  173. public String getExtensionName(T extensionInstance) {
  174. return getExtensionName(extensionInstance.getClass());
  175. }
  176. public String getExtensionName(Class<?> extensionClass) {
  177. return cachedNames.get(extensionClass);
  178. }
  179. public List<T> getActivateExtension(URL url, String key) {
  180. return getActivateExtension(url, key, null);
  181. }
  182. public List<T> getActivateExtension(URL url, String[] values) {
  183. return getActivateExtension(url, values, null);
  184. }
  185. /**
  186. * 获得符合自动激活条件的拓展对象数组
  187. */
  188. public List<T> getActivateExtension(URL url, String key, String group) {
  189. // 从 Dubbo URL 获得参数值
  190. String value = url.getParameter(key);
  191. // 获得符合自动激活条件的拓展对象数组
  192. return getActivateExtension(url, value == null || value.length() == 0 ? null : Constants.COMMA_SPLIT_PATTERN.split(value), group);
  193. }
  194. /**
  195. * 获得符合自动激活条件的拓展对象数组
  196. */
  197. public List<T> getActivateExtension(URL url, String[] values, String group) {
  198. List<T> exts = new ArrayList<T>();
  199. List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values);
  200. // 处理自动激活的拓展对象们
  201. // 判断不存在配置 `"-name"` 。例如,<dubbo:service filter="-default" /> ,代表移除所有默认过滤器。
  202. if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {
  203. // 获得拓展实现类数组
  204. getExtensionClasses();
  205. // 循环
  206. for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {
  207. String name = entry.getKey();
  208. Activate activate = entry.getValue();
  209. if (isMatchGroup(group, activate.group())) { // 匹配分组
  210. // 获得拓展对象
  211. T ext = getExtension(name);
  212. if (!names.contains(name) // 不包含在自定义配置里。如果包含,会在下面的代码处理。
  213. && !names.contains(Constants.REMOVE_VALUE_PREFIX + name) // 判断是否配置移除。例如 <dubbo:service filter="-monitor" />,则 MonitorFilter 会被移除
  214. && isActive(activate, url)) { // 判断是否激活
  215. exts.add(ext);
  216. }
  217. }
  218. }
  219. // 排序
  220. Collections.sort(exts, ActivateComparator.COMPARATOR);
  221. }
  222. // 处理自定义配置的拓展对象们。例如在 <dubbo:service filter="demo" /> ,代表需要加入 DemoFilter (这个是笔者自定义的)。
  223. List<T> usrs = new ArrayList<T>();
  224. for (int i = 0; i < names.size(); i++) {
  225. String name = names.get(i);
  226. if (!name.startsWith(Constants.REMOVE_VALUE_PREFIX) && !names.contains(Constants.REMOVE_VALUE_PREFIX + name)) { // 判断非移除的
  227. // 将配置的自定义在自动激活的拓展对象们前面。例如,<dubbo:service filter="demo,default,demo2" /> ,则 DemoFilter 就会放在默认的过滤器前面。
  228. if (Constants.DEFAULT_KEY.equals(name)) {
  229. if (!usrs.isEmpty()) {
  230. exts.addAll(0, usrs);
  231. usrs.clear();
  232. }
  233. } else {
  234. // 获得拓展对象
  235. T ext = getExtension(name);
  236. usrs.add(ext);
  237. }
  238. }
  239. }
  240. // 添加到结果集
  241. if (!usrs.isEmpty()) {
  242. exts.addAll(usrs);
  243. }
  244. return exts;
  245. }
  246. /**
  247. * 匹配分组
  248. *
  249. * @param group 过滤的分组条件。若为空,无需过滤
  250. * @param groups 配置的分组
  251. * @return 是否匹配
  252. */
  253. private boolean isMatchGroup(String group, String[] groups) {
  254. // 为空,无需过滤
  255. if (group == null || group.length() == 0) {
  256. return true;
  257. }
  258. // 匹配
  259. if (groups != null && groups.length > 0) {
  260. for (String g : groups) {
  261. if (group.equals(g)) {
  262. return true;
  263. }
  264. }
  265. }
  266. return false;
  267. }
  268. /**
  269. * 是否激活,通过 Dubbo URL 中是否存在参数名为 `@Activate.value` ,并且参数值非空。
  270. *
  271. * @param activate 自动激活注解
  272. * @param url Dubbo URL
  273. * @return 是否
  274. */
  275. private boolean isActive(Activate activate, URL url) {
  276. String[] keys = activate.value();
  277. if (keys.length == 0) {
  278. return true;
  279. }
  280. for (String key : keys) {
  281. for (Map.Entry<String, String> entry : url.getParameters().entrySet()) {
  282. String k = entry.getKey();
  283. String v = entry.getValue();
  284. if ((k.equals(key) || k.endsWith("." + key))
  285. && ConfigUtils.isNotEmpty(v)) {
  286. return true;
  287. }
  288. }
  289. }
  290. return false;
  291. }
  292. /**
  293. * 返回扩展点实例,如果没有指定的扩展点或是还没加载(即实例化)则返回<code>null</code>。
  294. * 注意:此方法不会触发扩展点的加载。
  295. * 一般应该调用{@link #getExtension(String)}方法获得扩展,这个方法会触发扩展点加载。
  296. */
  297. @SuppressWarnings("unchecked")
  298. public T getLoadedExtension(String name) {
  299. if (name == null || name.length() == 0)
  300. throw new IllegalArgumentException("Extension name == null");
  301. Holder<Object> holder = cachedInstances.get(name);
  302. if (holder == null) {
  303. cachedInstances.putIfAbsent(name, new Holder<Object>());
  304. holder = cachedInstances.get(name);
  305. }
  306. return (T) holder.get();
  307. }
  308. /**
  309. * 返回已经加载的扩展点的名字。
  310. * 一般应该调用 getSupportedExtensions() 方法获得扩展,这个方法会返回所有的扩展点。
  311. */
  312. public Set<String> getLoadedExtensions() {
  313. return Collections.unmodifiableSet(new TreeSet<String>(cachedInstances.keySet()));
  314. }
  315. /**
  316. * 返回指定名字的扩展对象。如果指定名字的扩展不存在,则抛异常 {@link IllegalStateException}.
  317. *
  318. * @param name 拓展名
  319. * @return 拓展对象
  320. */
  321. @SuppressWarnings("unchecked")
  322. public T getExtension(String name) {
  323. if (name == null || name.length() == 0)
  324. throw new IllegalArgumentException("Extension name == null");
  325. // 查找 默认的 拓展对象
  326. if ("true".equals(name)) {
  327. return getDefaultExtension();
  328. }
  329. // 从 缓存中 获得对应的拓展对象
  330. Holder<Object> holder = cachedInstances.get(name);
  331. if (holder == null) {
  332. cachedInstances.putIfAbsent(name, new Holder<Object>());
  333. holder = cachedInstances.get(name);
  334. }
  335. Object instance = holder.get();
  336. if (instance == null) {
  337. synchronized (holder) {
  338. instance = holder.get();
  339. // 从 缓存中 未获取到,进行创建缓存对象。
  340. if (instance == null) {
  341. instance = createExtension(name);
  342. // 设置创建对象到缓存中
  343. holder.set(instance);
  344. }
  345. }
  346. }
  347. return (T) instance;
  348. }
  349. /**
  350. * 返回缺省的扩展,如果没有设置则返回<code>null</code>。
  351. */
  352. public T getDefaultExtension() {
  353. getExtensionClasses();
  354. // 如果为 true ,不能继续调用 `#getExtension(true)` 方法,会形成死循环。
  355. if (null == cachedDefaultName || cachedDefaultName.length() == 0
  356. || "true".equals(cachedDefaultName)) {
  357. return null;
  358. }
  359. return getExtension(cachedDefaultName);
  360. }
  361. public boolean hasExtension(String name) {
  362. if (name == null || name.length() == 0)
  363. throw new IllegalArgumentException("Extension name == null");
  364. try {
  365. return getExtensionClass(name) != null;
  366. } catch (Throwable t) {
  367. return false;
  368. }
  369. }
  370. public Set<String> getSupportedExtensions() {
  371. Map<String, Class<?>> clazzes = getExtensionClasses();
  372. return Collections.unmodifiableSet(new TreeSet<String>(clazzes.keySet()));
  373. }
  374. /**
  375. * 返回缺省的扩展点名,如果没有设置缺省则返回<code>null</code>。
  376. */
  377. public String getDefaultExtensionName() {
  378. getExtensionClasses();
  379. return cachedDefaultName;
  380. }
  381. /**
  382. * 编程方式添加新扩展点。
  383. *
  384. * @param name 扩展点名
  385. * @param clazz 扩展点类
  386. * @throws IllegalStateException 要添加扩展点名已经存在。
  387. */
  388. public void addExtension(String name, Class<?> clazz) {
  389. getExtensionClasses(); // load classes
  390. if (!type.isAssignableFrom(clazz)) {
  391. throw new IllegalStateException("Input type " +
  392. clazz + "not implement Extension " + type);
  393. }
  394. if (clazz.isInterface()) {
  395. throw new IllegalStateException("Input type " +
  396. clazz + "can not be interface!");
  397. }
  398. if (!clazz.isAnnotationPresent(Adaptive.class)) {
  399. if (StringUtils.isBlank(name)) {
  400. throw new IllegalStateException("Extension name is blank (Extension " + type + ")!");
  401. }
  402. if (cachedClasses.get().containsKey(name)) {
  403. throw new IllegalStateException("Extension name " +
  404. name + " already existed(Extension " + type + ")!");
  405. }
  406. cachedNames.put(clazz, name);
  407. cachedClasses.get().put(name, clazz);
  408. } else {
  409. if (cachedAdaptiveClass != null) {
  410. throw new IllegalStateException("Adaptive Extension already existed(Extension " + type + ")!");
  411. }
  412. cachedAdaptiveClass = clazz;
  413. }
  414. }
  415. /**
  416. * 编程方式添加替换已有扩展点。
  417. *
  418. * @param name 扩展点名
  419. * @param clazz 扩展点类
  420. * @throws IllegalStateException 要添加扩展点名已经存在。
  421. * @deprecated 不推荐应用使用,一般只在测试时可以使用
  422. */
  423. @Deprecated
  424. public void replaceExtension(String name, Class<?> clazz) {
  425. getExtensionClasses(); // load classes
  426. if (!type.isAssignableFrom(clazz)) {
  427. throw new IllegalStateException("Input type " +
  428. clazz + "not implement Extension " + type);
  429. }
  430. if (clazz.isInterface()) {
  431. throw new IllegalStateException("Input type " +
  432. clazz + "can not be interface!");
  433. }
  434. if (!clazz.isAnnotationPresent(Adaptive.class)) {
  435. if (StringUtils.isBlank(name)) {
  436. throw new IllegalStateException("Extension name is blank (Extension " + type + ")!");
  437. }
  438. if (!cachedClasses.get().containsKey(name)) {
  439. throw new IllegalStateException("Extension name " +
  440. name + " not existed(Extension " + type + ")!");
  441. }
  442. cachedNames.put(clazz, name);
  443. cachedClasses.get().put(name, clazz);
  444. cachedInstances.remove(name);
  445. } else {
  446. if (cachedAdaptiveClass == null) {
  447. throw new IllegalStateException("Adaptive Extension not existed(Extension " + type + ")!");
  448. }
  449. cachedAdaptiveClass = clazz;
  450. cachedAdaptiveInstance.set(null);
  451. }
  452. }
  453. /**
  454. * 获得自适应拓展对象
  455. *
  456. * @return 拓展对象
  457. */
  458. @SuppressWarnings("unchecked")
  459. public T getAdaptiveExtension() {
  460. // 从缓存中,获得自适应拓展对象
  461. Object instance = cachedAdaptiveInstance.get();
  462. if (instance == null) {
  463. // 若之前未创建报错,
  464. if (createAdaptiveInstanceError == null) {
  465. synchronized (cachedAdaptiveInstance) {
  466. instance = cachedAdaptiveInstance.get();
  467. if (instance == null) {
  468. try {
  469. // 创建自适应拓展对象
  470. instance = createAdaptiveExtension();
  471. // 设置到缓存
  472. cachedAdaptiveInstance.set(instance);
  473. } catch (Throwable t) {
  474. // 记录异常
  475. createAdaptiveInstanceError = t;
  476. throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);
  477. }
  478. }
  479. }
  480. // 若之前创建报错,则抛出异常 IllegalStateException
  481. } else {
  482. throw new IllegalStateException("fail to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);
  483. }
  484. }
  485. return (T) instance;
  486. }
  487. /**
  488. * 获得拓展名不存在时的异常
  489. *
  490. * @param name 拓展名
  491. * @return 异常
  492. */
  493. private IllegalStateException findException(String name) {
  494. // 在 `#loadFile(...)` 方法中,加载时,发生异常
  495. for (Map.Entry<String, IllegalStateException> entry : exceptions.entrySet()) {
  496. if (entry.getKey().toLowerCase().contains(name.toLowerCase())) {
  497. return entry.getValue();
  498. }
  499. }
  500. // 生成不存在该拓展类实现的异常。
  501. StringBuilder buf = new StringBuilder("No such extension " + type.getName() + " by name " + name);
  502. int i = 1;
  503. for (Map.Entry<String, IllegalStateException> entry : exceptions.entrySet()) {
  504. if (i == 1) {
  505. buf.append(", possible causes: ");
  506. }
  507. buf.append("\r\n(");
  508. buf.append(i++);
  509. buf.append(") ");
  510. buf.append(entry.getKey());
  511. buf.append(":\r\n");
  512. buf.append(StringUtils.toString(entry.getValue()));
  513. }
  514. return new IllegalStateException(buf.toString());
  515. }
  516. /**
  517. * 创建拓展名的拓展对象,并缓存。
  518. *
  519. * @param name 拓展名
  520. * @return 拓展对象
  521. */
  522. @SuppressWarnings("unchecked")
  523. private T createExtension(String name) {
  524. // 获得拓展名对应的拓展实现类
  525. Class<?> clazz = getExtensionClasses().get(name);
  526. if (clazz == null) {
  527. throw findException(name); // 抛出异常
  528. }
  529. try {
  530. // 从缓存中,获得拓展对象。
  531. T instance = (T) EXTENSION_INSTANCES.get(clazz);
  532. if (instance == null) {
  533. // 当缓存不存在时,创建拓展对象,并添加到缓存中。
  534. EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
  535. instance = (T) EXTENSION_INSTANCES.get(clazz);
  536. }
  537. // 注入依赖的属性
  538. injectExtension(instance);
  539. // 创建 Wrapper 拓展对象
  540. Set<Class<?>> wrapperClasses = cachedWrapperClasses;
  541. if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
  542. for (Class<?> wrapperClass : wrapperClasses) {
  543. instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
  544. }
  545. }
  546. return instance;
  547. } catch (Throwable t) {
  548. throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
  549. type + ") could not be instantiated: " + t.getMessage(), t);
  550. }
  551. }
  552. /**
  553. * 注入依赖的属性
  554. *
  555. * @param instance 拓展对象
  556. * @return 拓展对象
  557. */
  558. private T injectExtension(T instance) {
  559. try {
  560. if (objectFactory != null) {
  561. for (Method method : instance.getClass().getMethods()) {
  562. if (method.getName().startsWith("set")
  563. && method.getParameterTypes().length == 1
  564. && Modifier.isPublic(method.getModifiers())) { // setting && public 方法
  565. // 获得属性的类型
  566. Class<?> pt = method.getParameterTypes()[0];
  567. try {
  568. // 获得属性
  569. String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
  570. // 获得属性值
  571. Object object = objectFactory.getExtension(pt, property);
  572. // 设置属性值
  573. if (object != null) {
  574. method.invoke(instance, object);
  575. }
  576. } catch (Exception e) {
  577. logger.error("fail to inject via method " + method.getName()
  578. + " of interface " + type.getName() + ": " + e.getMessage(), e);
  579. }
  580. }
  581. }
  582. }
  583. } catch (Exception e) {
  584. logger.error(e.getMessage(), e);
  585. }
  586. return instance;
  587. }
  588. private Class<?> getExtensionClass(String name) {
  589. if (type == null)
  590. throw new IllegalArgumentException("Extension type == null");
  591. if (name == null)
  592. throw new IllegalArgumentException("Extension name == null");
  593. // 获得拓展实现类
  594. Class<?> clazz = getExtensionClasses().get(name);
  595. if (clazz == null)
  596. throw new IllegalStateException("No such extension \"" + name + "\" for " + type.getName() + "!");
  597. return clazz;
  598. }
  599. /**
  600. * 获得拓展实现类数组
  601. *
  602. * @return 拓展实现类数组
  603. */
  604. private Map<String, Class<?>> getExtensionClasses() {
  605. // 从缓存中,获得拓展实现类数组
  606. Map<String, Class<?>> classes = cachedClasses.get();
  607. if (classes == null) {
  608. synchronized (cachedClasses) {
  609. classes = cachedClasses.get();
  610. if (classes == null) {
  611. // 从配置文件中,加载拓展实现类数组
  612. classes = loadExtensionClasses();
  613. // 设置到缓存中
  614. cachedClasses.set(classes);
  615. }
  616. }
  617. }
  618. return classes;
  619. }
  620. /**
  621. * 加载拓展实现类数组
  622. *
  623. * @return 拓展实现类数组
  624. */
  625. private Map<String, Class<?>> loadExtensionClasses() {
  626. // 通过 @SPI 注解,获得默认的拓展实现类名
  627. final SPI defaultAnnotation = type.getAnnotation(SPI.class);
  628. if (defaultAnnotation != null) {
  629. String value = defaultAnnotation.value();
  630. if ((value = value.trim()).length() > 0) {
  631. String[] names = NAME_SEPARATOR.split(value);
  632. if (names.length > 1) {
  633. throw new IllegalStateException("more than 1 default extension name on extension " + type.getName()
  634. + ": " + Arrays.toString(names));
  635. }
  636. if (names.length == 1) cachedDefaultName = names[0];
  637. }
  638. }
  639. // 从配置文件中,加载拓展实现类数组
  640. Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>();
  641. loadFile(extensionClasses, DUBBO_INTERNAL_DIRECTORY);
  642. loadFile(extensionClasses, DUBBO_DIRECTORY);
  643. loadFile(extensionClasses, SERVICES_DIRECTORY);
  644. return extensionClasses;
  645. }
  646. /**
  647. * 从一个配置文件中,加载拓展实现类数组。
  648. *
  649. * @param extensionClasses 拓展类名数组
  650. * @param dir 文件名
  651. */
  652. private void loadFile(Map<String, Class<?>> extensionClasses, String dir) {
  653. // 完整的文件名
  654. String fileName = dir + type.getName();
  655. try {
  656. Enumeration<java.net.URL> urls;
  657. // 获得文件名对应的所有文件数组
  658. ClassLoader classLoader = findClassLoader();
  659. if (classLoader != null) {
  660. urls = classLoader.getResources(fileName);
  661. } else {
  662. urls = ClassLoader.getSystemResources(fileName);
  663. }
  664. // 遍历文件数组
  665. if (urls != null) {
  666. while (urls.hasMoreElements()) {
  667. java.net.URL url = urls.nextElement();
  668. try {
  669. BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
  670. try {
  671. String line;
  672. while ((line = reader.readLine()) != null) {
  673. // 跳过当前被注释掉的情况,例如 #spring=xxxxxxxxx
  674. final int ci = line.indexOf('#');
  675. if (ci >= 0) line = line.substring(0, ci);
  676. line = line.trim();
  677. if (line.length() > 0) {
  678. try {
  679. // 拆分,key=value 的配置格式
  680. String name = null;
  681. int i = line.indexOf('=');
  682. if (i > 0) {
  683. name = line.substring(0, i).trim();
  684. line = line.substring(i + 1).trim();
  685. }
  686. if (line.length() > 0) {
  687. // 判断拓展实现,是否实现拓展接口
  688. Class<?> clazz = Class.forName(line, true, classLoader);
  689. if (!type.isAssignableFrom(clazz)) {
  690. throw new IllegalStateException("Error when load extension class(interface: " +
  691. type + ", class line: " + clazz.getName() + "), class "
  692. + clazz.getName() + "is not subtype of interface.");
  693. }
  694. // 缓存自适应拓展对象的类到 `cachedAdaptiveClass`
  695. if (clazz.isAnnotationPresent(Adaptive.class)) {
  696. if (cachedAdaptiveClass == null) {
  697. cachedAdaptiveClass = clazz;
  698. } else if (!cachedAdaptiveClass.equals(clazz)) {
  699. throw new IllegalStateException("More than 1 adaptive class found: "
  700. + cachedAdaptiveClass.getClass().getName()
  701. + ", " + clazz.getClass().getName());
  702. }
  703. } else {
  704. // 缓存拓展 Wrapper 实现类到 `cachedWrapperClasses`
  705. try {
  706. clazz.getConstructor(type);
  707. Set<Class<?>> wrappers = cachedWrapperClasses;
  708. if (wrappers == null) {
  709. cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();
  710. wrappers = cachedWrapperClasses;
  711. }
  712. wrappers.add(clazz);
  713. // 缓存拓展实现类到 `extensionClasses`
  714. } catch (NoSuchMethodException e) {
  715. clazz.getConstructor();
  716. // 未配置拓展名,自动生成。例如,DemoFilter 为 demo 。主要用于兼容 Java SPI 的配置。
  717. if (name == null || name.length() == 0) {
  718. name = findAnnotationName(clazz);
  719. if (name == null || name.length() == 0) {
  720. if (clazz.getSimpleName().length() > type.getSimpleName().length()
  721. && clazz.getSimpleName().endsWith(type.getSimpleName())) {
  722. name = clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - type.getSimpleName().length()).toLowerCase();
  723. } else {
  724. throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + url);
  725. }
  726. }
  727. }
  728. // 获得拓展名,可以是数组,有多个拓展名。
  729. String[] names = NAME_SEPARATOR.split(name);
  730. if (names != null && names.length > 0) {
  731. // 缓存 @Activate 到 `cachedActivates` 。
  732. Activate activate = clazz.getAnnotation(Activate.class);
  733. if (activate != null) {
  734. cachedActivates.put(names[0], activate);
  735. }
  736. for (String n : names) {
  737. // 缓存到 `cachedNames`
  738. if (!cachedNames.containsKey(clazz)) {
  739. cachedNames.put(clazz, n);
  740. }
  741. // 缓存拓展实现类到 `extensionClasses`
  742. Class<?> c = extensionClasses.get(n);
  743. if (c == null) {
  744. extensionClasses.put(n, clazz);
  745. } else if (c != clazz) {
  746. throw new IllegalStateException("Duplicate extension " + type.getName() + " name " + n + " on " + c.getName() + " and " + clazz.getName());
  747. }
  748. }
  749. }
  750. }
  751. }
  752. }
  753. } catch (Throwable t) {
  754. // 发生异常,记录到异常集合
  755. IllegalStateException e = new IllegalStateException("Failed to load extension class(interface: " + type + ", class line: " + line + ") in " + url + ", cause: " + t.getMessage(), t);
  756. exceptions.put(line, e);
  757. }
  758. }
  759. } // end of while read lines
  760. } finally {
  761. reader.close();
  762. }
  763. } catch (Throwable t) {
  764. logger.error("Exception when load extension class(interface: " +
  765. type + ", class file: " + url + ") in " + url, t);
  766. }
  767. } // end of while urls
  768. }
  769. } catch (Throwable t) {
  770. logger.error("Exception when load extension class(interface: " +
  771. type + ", description file: " + fileName + ").", t);
  772. }
  773. }
  774. @SuppressWarnings("deprecation")
  775. private String findAnnotationName(Class<?> clazz) {
  776. com.alibaba.dubbo.common.Extension extension = clazz.getAnnotation(com.alibaba.dubbo.common.Extension.class);
  777. if (extension == null) {
  778. String name = clazz.getSimpleName();
  779. if (name.endsWith(type.getSimpleName())) {
  780. name = name.substring(0, name.length() - type.getSimpleName().length());
  781. }
  782. return name.toLowerCase();
  783. }
  784. return extension.value();
  785. }
  786. /**
  787. * 创建自适应拓展对象
  788. *
  789. * @return 拓展对象
  790. */
  791. @SuppressWarnings("unchecked")
  792. private T createAdaptiveExtension() {
  793. try {
  794. return injectExtension((T) getAdaptiveExtensionClass().newInstance());
  795. } catch (Exception e) {
  796. throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);
  797. }
  798. }
  799. /**
  800. * @return 自适应拓展类
  801. */
  802. private Class<?> getAdaptiveExtensionClass() {
  803. getExtensionClasses();
  804. if (cachedAdaptiveClass != null) {
  805. return cachedAdaptiveClass;
  806. }
  807. return cachedAdaptiveClass = createAdaptiveExtensionClass();
  808. }
  809. /**
  810. * 自动生成自适应拓展的代码实现,并编译后返回该类。
  811. *
  812. * @return 类
  813. */
  814. private Class<?> createAdaptiveExtensionClass() {
  815. // 自动生成自适应拓展的代码实现的字符串
  816. String code = createAdaptiveExtensionClassCode();
  817. // 编译代码,并返回该类
  818. ClassLoader classLoader = findClassLoader();
  819. com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
  820. return compiler.compile(code, classLoader);
  821. }
  822. /**
  823. * 自动生成自适应拓展的代码实现的字符串
  824. *
  825. * @return 代码字符串
  826. */
  827. private String createAdaptiveExtensionClassCode() {
  828. StringBuilder codeBuidler = new StringBuilder();
  829. // 遍历方法数组,判断有 @Adaptive 注解
  830. Method[] methods = type.getMethods();
  831. boolean hasAdaptiveAnnotation = false;
  832. for (Method m : methods) {
  833. if (m.isAnnotationPresent(Adaptive.class)) {
  834. hasAdaptiveAnnotation = true;
  835. break;
  836. }
  837. }
  838. // no need to generate adaptive class since there's no adaptive method found.
  839. // 完全没有Adaptive方法,则不需要生成Adaptive类
  840. if (!hasAdaptiveAnnotation)
  841. throw new IllegalStateException("No adaptive method on extension " + type.getName() + ", refuse to create the adaptive class!");
  842. // 生成代码:package 和 import
  843. codeBuidler.append("package " + type.getPackage().getName() + ";");
  844. codeBuidler.append("\nimport " + ExtensionLoader.class.getName() + ";");
  845. // 生成代码:类名
  846. codeBuidler.append("\npublic class " + type.getSimpleName() + "$Adaptive" + " implements " + type.getCanonicalName() + " {");
  847. // 循环方法
  848. for (Method method : methods) {
  849. Class<?> rt = method.getReturnType(); // 返回类型
  850. Class<?>[] pts = method.getParameterTypes(); // 参数类型数组
  851. Class<?>[] ets = method.getExceptionTypes(); // 异常类型数组
  852. Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
  853. StringBuilder code = new StringBuilder(512); // 方法体的代码
  854. // 非 @Adaptive 注解,生成代码:生成的方法为直接抛出异常。因为,非自适应的接口不应该被调用。
  855. if (adaptiveAnnotation == null) {
  856. code.append("throw new UnsupportedOperationException(\"method ")
  857. .append(method.toString()).append(" of interface ")
  858. .append(type.getName()).append(" is not adaptive method!\");");
  859. // @Adaptive 注解,生成方法体的代码
  860. } else {
  861. // 寻找 Dubbo URL 参数的位置
  862. int urlTypeIndex = -1;
  863. for (int i = 0; i < pts.length; ++i) {
  864. if (pts[i].equals(URL.class)) {
  865. urlTypeIndex = i;
  866. break;
  867. }
  868. }
  869. // found parameter in URL type
  870. // 有类型为URL的参数,生成代码:生成校验 URL 非空的代码
  871. if (urlTypeIndex != -1) {
  872. // Null Point check
  873. String s = String.format("\nif (arg%d == null) throw new IllegalArgumentException(\"url == null\");",
  874. urlTypeIndex);
  875. code.append(s);
  876. s = String.format("\n%s url = arg%d;", URL.class.getName(), urlTypeIndex);
  877. code.append(s);
  878. }
  879. // did not find parameter in URL type
  880. // 参数没有URL类型
  881. else {
  882. String attribMethod = null;
  883. // find URL getter method
  884. // 找到参数的URL属性 。例如,Invoker 有 `#getURL()` 方法。
  885. LBL_PTS:
  886. for (int i = 0; i < pts.length; ++i) {
  887. Method[] ms = pts[i].getMethods();
  888. for (Method m : ms) {
  889. String name = m.getName();
  890. if ((name.startsWith("get") || name.length() > 3)
  891. && Modifier.isPublic(m.getModifiers())
  892. && !Modifier.isStatic(m.getModifiers())
  893. && m.getParameterTypes().length == 0
  894. && m.getReturnType() == URL.class) { // pubic && getting 方法
  895. urlTypeIndex = i;
  896. attribMethod = name;
  897. break LBL_PTS;
  898. }
  899. }
  900. }
  901. // 未找到,抛出异常。
  902. if (attribMethod == null) {
  903. throw new IllegalStateException("fail to create adaptive class for interface " + type.getName()
  904. + ": not found url parameter or url attribute in parameters of method " + method.getName());
  905. }
  906. // 生成代码:校验 URL 非空
  907. // Null point check
  908. String s = String.format("\nif (arg%d == null) throw new IllegalArgumentException(\"%s argument == null\");",
  909. urlTypeIndex, pts[urlTypeIndex].getName());
  910. code.append(s);
  911. s = String.format("\nif (arg%d.%s() == null) throw new IllegalArgumentException(\"%s argument %s() == null\");",
  912. urlTypeIndex, attribMethod, pts[urlTypeIndex].getName(), attribMethod);
  913. code.append(s);
  914. // 生成 `URL url = arg%d.%s();` 的代码
  915. s = String.format("%s url = arg%d.%s();", URL.class.getName(), urlTypeIndex, attribMethod);
  916. code.append(s);
  917. }
  918. String[] value = adaptiveAnnotation.value();
  919. // value is not set, use the value generated from class name as the key
  920. // 没有设置Key,则使用“扩展点接口名的点分隔 作为Key
  921. if (value.length == 0) {
  922. char[] charArray = type.getSimpleName().toCharArray();
  923. StringBuilder sb = new StringBuilder(128);
  924. for (int i = 0; i < charArray.length; i++) {
  925. if (Character.isUpperCase(charArray[i])) {
  926. if (i != 0) {
  927. sb.append(".");
  928. }
  929. sb.append(Character.toLowerCase(charArray[i]));
  930. } else {
  931. sb.append(charArray[i]);
  932. }
  933. }
  934. value = new String[]{sb.toString()};
  935. }
  936. // 判断是否有 Invocation 参数
  937. boolean hasInvocation = false;
  938. for (int i = 0; i < pts.length; ++i) {
  939. if (pts[i].getName().equals("com.alibaba.dubbo.rpc.Invocation")) {
  940. // 生成代码:校验 Invocation 非空
  941. // Null Point check
  942. String s = String.format("\nif (arg%d == null) throw new IllegalArgumentException(\"invocation == null\");", i);
  943. code.append(s);
  944. // 生成代码:获得方法名
  945. s = String.format("\nString methodName = arg%d.getMethodName();", i);
  946. code.append(s);
  947. // 标记有 Invocation 参数
  948. hasInvocation = true;
  949. break;
  950. }
  951. }
  952. // 默认拓展名
  953. String defaultExtName = cachedDefaultName;
  954. // 获得最终拓展名的代码字符串,例如:
  955. // 【简单】1. url.getParameter("proxy", "javassist")
  956. // 【复杂】2. url.getParameter(key1, url.getParameter(key2, defaultExtName))
  957. String getNameCode = null;
  958. for (int i = value.length - 1; i >= 0; --i) { // 倒序的原因,因为是顺序获取参数,参见【复杂】2. 的例子
  959. if (i == value.length - 1) {
  960. if (null != defaultExtName) {
  961. if (!"protocol".equals(value[i]))
  962. if (hasInvocation) // 当【有】 Invocation 参数时,使用 `URL#getMethodParameter()` 方法。
  963. getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);
  964. else // 当【非】 Invocation 参数时,使用 `URL#getParameter()` 方法。
  965. getNameCode = String.format("url.getParameter(\"%s\", \"%s\")", value[i], defaultExtName);
  966. else // 当属性名是 "protocol" ,使用 `URL#getProtocl()` 方法获取。
  967. getNameCode = String.format("( url.getProtocol() == null ? \"%s\" : url.getProtocol() )", defaultExtName);
  968. } else {
  969. if (!"protocol".equals(value[i]))
  970. if (hasInvocation)
  971. getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName); // 此处的 defaultExtName ,可以去掉的。
  972. else
  973. getNameCode = String.format("url.getParameter(\"%s\")", value[i]);
  974. else
  975. getNameCode = "url.getProtocol()";
  976. }
  977. } else {
  978. if (!"protocol".equals(value[i]))
  979. if (hasInvocation)
  980. getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);
  981. else
  982. getNameCode = String.format("url.getParameter(\"%s\", %s)", value[i], getNameCode);
  983. else
  984. getNameCode = String.format("url.getProtocol() == null ? (%s) : url.getProtocol()", getNameCode);
  985. }
  986. }
  987. // 生成代码:获取参数的代码。例如:String extName = url.getParameter("proxy", "javassist");
  988. code.append("\nString extName = ").append(getNameCode).append(";");
  989. // check extName == null?
  990. String s = String.format("\nif(extName == null) " +
  991. "throw new IllegalStateException(\"Fail to get extension(%s) name from url(\" + url.toString() + \") use keys(%s)\");",
  992. type.getName(), Arrays.toString(value));
  993. code.append(s);
  994. // 生成代码:拓展对象,调用方法。例如
  995. // `com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class)
  996. // .getExtension(extName);` 。
  997. s = String.format("\n%s extension = (%<s)%s.getExtensionLoader(%s.class).getExtension(extName);",
  998. type.getName(), ExtensionLoader.class.getSimpleName(), type.getName());
  999. code.append(s);
  1000. // return statement
  1001. if (!rt.equals(void.class)) {
  1002. code.append("\nreturn ");
  1003. }
  1004. s = String.format("extension.%s(", method.getName());
  1005. code.append(s);
  1006. for (int i = 0; i < pts.length; i++) {
  1007. if (i != 0)
  1008. code.append(", ");
  1009. code.append("arg").append(i);
  1010. }
  1011. code.append(");");
  1012. }
  1013. // 生成方法
  1014. codeBuidler.append("\npublic " + rt.getCanonicalName() + " " + method.getName() + "(");
  1015. for (int i = 0; i < pts.length; i++) {
  1016. if (i > 0) {
  1017. codeBuidler.append(", ");
  1018. }
  1019. codeBuidler.append(pts[i].getCanonicalName());
  1020. codeBuidler.append(" ");
  1021. codeBuidler.append("arg" + i);
  1022. }
  1023. codeBuidler.append(")");
  1024. if (ets.length > 0) {
  1025. codeBuidler.append(" throws "); // 异常
  1026. for (int i = 0; i < ets.length; i++) {
  1027. if (i > 0) {
  1028. codeBuidler.append(", ");
  1029. }
  1030. codeBuidler.append(ets[i].getCanonicalName());
  1031. }
  1032. }
  1033. codeBuidler.append(" {");
  1034. codeBuidler.append(code.toString());
  1035. codeBuidler.append("\n}");
  1036. }
  1037. // 生成类末尾的 `}`
  1038. codeBuidler.append("\n}");
  1039. // 调试,打印生成的代码
  1040. if (logger.isDebugEnabled()) {
  1041. logger.debug(codeBuidler.toString());
  1042. }
  1043. return codeBuidler.toString();
  1044. }
  1045. @Override
  1046. public String toString() {
  1047. return this.getClass().getName() + "[" + type.getName() + "]";
  1048. }
  1049. }