下面示例中,使用@spi、@adaptive、@wrapper,了解其作用
Geek
@SPI("dubbo")
public interface Geek {
@Adaptive
String getCourse(URL url);
@Adaptive({"custom", "geek"})
String getCourse2(URL url);
}
public class Dubbo implements Geek {
@Override
public String getCourse(URL url) {
return "Dubbo实战进阶课程";
}
@Override
public String getCourse2(URL url) {
return "Dubbo实战进阶课程(2)";
}
}
public class SpringCloud implements Geek {
@Override
public String getCourse(URL url) {
return "SpringCloud入门课程100集";
}
@Override
public String getCourse2(URL url) {
return "SpringCloud入门课程100集(2)";
}
}
wrapper
@Wrapper(order = 10, mismatches = {"springcloud"})
public class GeekWrapper implements Geek {
private Geek geek;
private Animal monkey;
public void setMonkey(Animal monkey){
this.monkey = monkey;
}
public GeekWrapper(Geek geek) {
this.geek = geek;
}
@Override
public String getCourse(URL url) {
return "【课程GeekWrapper前...】" + geek.getCourse(url) + "【课程GeekWrapper后...】||【"+monkey.eat(url)+"】";
}
@Override
public String getCourse2(URL url) {
return "【课程2前...】" + geek.getCourse2(url) + "【课程2后...】";
}
}
@Wrapper(order = 1)
public class AppleWrapper implements Geek {
private Geek geek;
public AppleWrapper(Geek geek) {
this.geek = geek;
}
@Override
public String getCourse(URL url) {
return "【课程AppleWrapper前...】" + geek.getCourse(url) + "【课程AppleWrapper后...】";
}
@Override
public String getCourse2(URL url) {
return "【课程2前...】" + geek.getCourse2(url) + "【课程2后...】";
}
}
adaptive,作用在方法上,会根据javassist生成动态类
@SPI("monkey")
public interface Animal {
@Adaptive
String eat(URL url);
}
public class Monkey implements Animal{
@Override
public String eat(URL url) {
return "猴子吃香蕉";
}
}
配置文件
application.properties
server.port=8180
META—INF.dubbo下的spi文件
com.hmilyylimh.cloud.inject.spi.Animal
monkey=com.hmilyylimh.cloud.inject.spi.Monkey
com.hmilyylimh.cloud.inject.spi.Geek
dubbo=com.hmilyylimh.cloud.inject.spi.Dubbo
springcloud=com.hmilyylimh.cloud.inject.spi.SpringCloud
com.hmilyylimh.cloud.inject.spi.GeekWrapper
com.hmilyylimh.cloud.inject.spi.AppleWrapper
测试入口
public class Dubbo18DubboInjectApplication {
public static void main(String[] args) {
ApplicationModel applicationModel = ApplicationModel.defaultModel();
// 通过 Geek 接口获取指定像 扩展点加载器
ExtensionLoader<Geek> extensionLoader = applicationModel.getExtensionLoader(Geek.class);
Geek geek = extensionLoader.getAdaptiveExtension();
System.out.println("日志1:【指定的 geek=springcloud 的情况】动态获取结果为: "
+ geek.getCourse(URL.valueOf("xyz://127.0.0.1/?geek=springcloud")));
System.out.println("日志2:【指定的 geek=dubbo 的情况】动态获取结果为: "
+ geek.getCourse(URL.valueOf("xyz://127.0.0.1/?geek=dubbo")));
System.out.println("日志3:【不指定的 geek 走默认情况】动态获取结果为: "
+ geek.getCourse(URL.valueOf("xyz://127.0.0.1/")));
}
}
通过adaptive动态生成的代理类,反编译代码如下,底层还是依赖getExtension方法
public class Geek$Adaptive implements com.hmilyylimh.cloud.inject.spi.Geek {
public java.lang.String getCourse(org.apache.dubbo.common.URL arg0) {
if (arg0 == null) throw new IllegalArgumentException("url == null");
org.apache.dubbo.common.URL url = arg0;
String extName = url.getParameter("geek", "dubbo");
if (extName == null)
throw new IllegalStateException("Failed to get extension (com.hmilyylimh.cloud.inject.spi.Geek) name from" +
" url (" + url.toString() + ") use keys([geek])");
ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(),
com.hmilyylimh.cloud.inject.spi.Geek.class);
com.hmilyylimh.cloud.inject.spi.Geek extension =
(com.hmilyylimh.cloud.inject.spi.Geek) scopeModel.getExtensionLoader(com.hmilyylimh.cloud.inject.spi.Geek.class).getExtension(extName);
return extension.getCourse(arg0);
}
@Override
public String getCourse2(URL url) {
return null;
}
}