概述
1、dubbo SPI区别于JDK SPI,根据指定的key值,获取接口对应的实现,具体由下面支付示例展示:
订单支付接口,使用@SPI 注解标注,默认是阿里支付
package spi;
import com.alibaba.dubbo.common.extension.SPI;
/**
* @Author: zhangshaolong001
* @Date: 2020/4/15 11:18 AM
* @Description:
*/
@SPI("aliPay")
public interface Order {
String payType();
}
阿里支付实现:
package spi.extension;
import spi.Order;
/**
* @Author: zhangshaolong001
* @Date: 2020/4/15 11:20 AM
* @Description:
*/
public class AlipayOrder implements Order {
@Override
public String payType() {
return "支付宝支付";
}
}
微信支付实现:
package spi.extension;
import spi.Order;
/**
* @Author: zhangshaolong001
* @Date: 2020/4/15 11:21 AM
* @Description:
*/
public class WeChatOrder implements Order {
@Override
public String payType() {
return "微信支付";
}
}
默认情况下,自适配实现
package spi.extension;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import org.springframework.util.StringUtils;
import spi.Order;
/**
* @Author: zhangshaolong001
* @Date: 2020/4/15 8:08 PM
* @Description:
*/
public class AdaptiveOrder implements Order{
private String payType;
public void setPayType(String payType) {
this.payType = payType;
}
@Override
public String payType() {
ExtensionLoader<Order> extensionLoader = ExtensionLoader.getExtensionLoader(Order.class);
Order orderPay;
if (StringUtils.isEmpty(this.payType)){
orderPay = extensionLoader.getDefaultExtension();
}else {
orderPay = extensionLoader.getExtension(this.payType);
}
return orderPay.payType();
}
}
配置文件:resources资源下,/META-INF/dubbo/internal文件夹下spi.Order命名的文件,也就是接口名:
aliPay=spi.extension.AlipayOrder
weChat=spi.extension.WeChatOrder
测试类
package spi;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
/**
* @Author: zhangshaolong001
* @Date: 2020/4/15 11:22 AM
* @Description:
*/
public class OrderPayTest {
public static void main(String[] args) {
ExtensionLoader<Order> extensionLoader = ExtensionLoader.getExtensionLoader(Order.class);
Order orderPay = extensionLoader.getDefaultExtension();
System.out.println(orderPay.payType());
orderPay = extensionLoader.getExtension("weChat");
System.out.println(orderPay.payType());
}
}
以下代码来自 com.alibaba.dubbo.common.extension.ExtensionLoader
创建对象:
private T createExtension(String name) {
//通过名称获取对应的类
Class<?> clazz = getExtensionClasses().get(name);
if (clazz == null) {
throw findException(name);
}
try {
T instance = (T) EXTENSION_INSTANCES.get(clazz);
if (instance == null) {
//通过反射创建类的对象实例
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
//给对象注入属性
injectExtension(instance);
Set<Class<?>> wrapperClasses = cachedWrapperClasses;
if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
for (Class<?> wrapperClass : wrapperClasses) {
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
}
}
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
type + ") could not be instantiated: " + t.getMessage(), t);
}
}
//注入属性
private T injectExtension(T instance) {
try {
if (objectFactory != null) {
for (Method method : instance.getClass().getMethods()) {
//判断是否是set方法
if (method.getName().startsWith("set")
&& method.getParameterTypes().length == 1
&& Modifier.isPublic(method.getModifiers())) {
Class<?> pt = method.getParameterTypes()[0];
try {
String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
Object object = objectFactory.getExtension(pt, property);
if (object != null) {
method.invoke(instance, object);
}
} catch (Exception e) {
logger.error("fail to inject via method " + method.getName()
+ " of interface " + type.getName() + ": " + e.getMessage(), e);
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return instance;
}
最后
以上就是机智蜻蜓为你收集整理的Dubbo SPI机制示例的全部内容,希望文章能够帮你解决Dubbo SPI机制示例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复