- # Comment 1 impl1 = com.alibaba.dubbo.common.extensionloader.ext1.impl.SimpleExtImpl1#Hello World impl2 = com.alibaba.dubbo.common.extensionloader.ext1.impl.SimpleExtImpl2 # Comment 2 impl3 = com.alibaba.dubbo.common.extensionloader.ext1.impl.SimpleExtImpl3 # with head space
定义 3 个实现。
1.4 测试
- @Test public void test_getDefaultExtension() throws Exception { SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getDefaultExtension(); assertThat(ext, instanceOf(SimpleExtImpl1.class)); String name = ExtensionLoader.getExtensionLoader(SimpleExt.class).getDefaultExtensionName(); assertEquals("impl1", name);
- }
{aa8aa}("impl1"),定义了默认实现的名称为 imp1.
- @Test public void test_getExtension() throws Exception { assertTrue(ExtensionLoader.getExtensionLoader(SimpleExt.class).getExtension("impl1") instanceof SimpleExtImpl1); assertTrue(ExtensionLoader.getExtensionLoader(SimpleExt.class).getExtension("impl2") instanceof SimpleExtImpl2);
- }
getExtensionLoader(Class<T> type): 根据类名,返回具体实现类。这些配置信息在 META 对应文件中配置。当然,{aa7aa}(只不过,这个注解已经废弃了)
- @Test public void test_getAdaptiveExtension_defaultAdaptiveKey() throws Exception { { SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getAdaptiveExtension(); Map < String,
- String > map = new HashMap < String,
- String > (); //没有指定具体parameters参数,所以选用默认实现,最后返回impl1
- URL url = new URL("p1", "1.2.3.4", 1010, "path1", map); //如果不设置默认的SPI实现类,则报异常
- //java.lang.IllegalStateException: Fail to get extension(com.alibaba.dubbo.common.extensionloader.ext1.SimpleExt) name from url(p1://1.2.3.4:1010/path1) use keys([simple.ext])
- String echo = ext.echo(url, "haha"); assertEquals("Ext1Impl1-echo", echo);
- } { SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getAdaptiveExtension(); Map < String,
- String > map = new HashMap < String,
- String > (); map.put("simple.ext", "impl2"); //手动在参数中配置impl2,参数为simple.ext
- URL url = new URL("p1", "1.2.3.4", 1010, "path1", map); String echo = ext.echo(url, "haha"); assertEquals("Ext1Impl2-echo", echo);
- }
- }
@Adaptive 测试
由于 yell 方法声明了,@Adaptive({"key1", "key2"})
- @Test public void test_getAdaptiveExtension_customizeAdaptiveKey() throws Exception { SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getAdaptiveExtension(); Map < String,
- String > map = new HashMap < String,
- String > (); map.put("key2", "impl2"); URL url = new URL("p1", "1.2.3.4", 1010, "path1", map); String echo = ext.yell(url, "haha"); assertEquals("Ext1Impl2-yell", echo); url = url.addParameter("key1", "impl3"); // 注意: URL是值类型
- echo = ext.yell(url, "haha"); assertEquals("Ext1Impl3-yell", echo);
- }
如果参数不是 key1,key2, 即使参数值输入 impl1,impl2 也是无意义的。
由于 bang 方法,{aa5aa} 修饰,所以以下代码,会报异常
ExtensionLoader.getExtensionLoader(SimpleExt.class).getAdaptiveExtension().bang(..);
of interface com.alibaba.dubbo.common.extensionloader.ext1.SimpleExt is not adaptive method!
以上内容,是通过代码演练的方式,讲解了 dubbo SPI 机制的威力。
如果对底层实现感兴趣,可参看博客。
来源: http://www.bubuko.com/infodetail-1865214.html