SPI简介
SPI 全称为 Service Provider Interface,是一种服务发现机制.
说白了是啥呢,比如你有个接口,该接口有3个实现类,那么在系统运行时,这个接口到底选择哪个实现类呢?这就需要SPI了,需要根据指定的配置或者是默认的配置,找到对应的实现类加载进来,然后使用该实现类的实例.
@SPI("alipay")
public interface IOrderService {
//支付方式
String way();
}
public class AlipayOrderImpl implements IOrderService {
@Override
public String way() {
System.out.println("---支付宝way()---");
return "支付宝支付";
}
}
public class WeChatOrderImpl implements IOrderService {
@Override
public String way() {
System.out.println("---微信way()---");
return "微信支付";
}
}
alipay=com.city.common.spi.extension.AlipayOrderImpl
weChat=com.city.common.spi.extension.WeChatOrderImpl
public class SPITest {
@Test
public void test1(){
ExtensionLoader<IOrderService> loader = ExtensionLoader.getExtensionLoader(IOrderService.class);
//加载
IOrderService alipay = loader.getExtension("alipay");
System.out.println(alipay.way());
IOrderService weChat = loader.getExtension("weChat");
System.out.println(weChat.way());
}
}
Adaptive自适应扩展类加载
jdk自带编译方式
javassist dubbo默认编译方式
类的扩展
@Adaptive
public class AdaptiveOrderImpl implements IOrderService {
//扩展类名
private String orderName;
public void setOrderName(String orderName) {
this.orderName = orderName;
}
@Override
public String way() {
//获取IOrderService实例
ExtensionLoader<IOrderService> loader = ExtensionLoader.getExtensionLoader(IOrderService.class);
IOrderService order;
if(StringUtils.isEmpty(orderName)){
//获取默认的实例
order = loader.getDefaultExtension();
}else{
//获取指定实例
order = loader.getExtension(orderName);
}
return order.way();
}
}
adaptive=com.city.common.spi.adaptive.AdaptiveOrderImpl
public class AdaptiveClassTest {
@Test
public void test01(){
ExtensionLoader<IOrderService> loader = ExtensionLoader.getExtensionLoader(IOrderService.class);
//获取自适应扩展类
IOrderService adativeExtension = loader.getAdaptiveExtension();
((AdaptiveOrderImpl)adativeExtension).setOrderName("weChat");
System.out.println(adativeExtension.way());
}
@Test
public void test02(){
ExtensionLoader<IOrderService> loader = ExtensionLoader.getExtensionLoader(IOrderService.class);
//获取自适应扩展类
IOrderService adativeExtension = loader.getAdaptiveExtension();
System.out.println(adativeExtension.way());
}
@Test
public void test03(){
ExtensionLoader<IOrderService> loader = ExtensionLoader.getExtensionLoader(IOrderService.class);
//获取真正的扩展类
Set<String> extensions = loader.getSupportedExtensions();
System.out.println(extensions);
}
}
方法的扩展
@SPI("alipay")
public interface IOrderService {
//支付方式
String way();
@Adaptive
String pay(URL url);
}
alipay=com.city.common.spi.extension.AlipayOrderImpl
weChat=com.city.common.spi.extension.WeChatOrderImpl
public class AdaptiveMethodTest {
@Test
public void test01(){
ExtensionLoader<IOrderService> loader = ExtensionLoader.getExtensionLoader(IOrderService.class);
//获取自适应扩展类
IOrderService adaptiveExtension = loader.getAdaptiveExtension();
//模拟一个URL
URL url = URL.valueOf("xxxx://localhost/ooo");
System.out.println(adaptiveExtension.pay(url));
}
@Test
public void test02(){
ExtensionLoader<IOrderService> loader = ExtensionLoader.getExtensionLoader(IOrderService.class);
//获取自适应扩展类
IOrderService adaptiveExtension = loader.getAdaptiveExtension();
//模拟一个URL
URL url = URL.valueOf("xxxx://localhost/ooo?i.order.service=weChat");
System.out.println(adaptiveExtension.pay(url));
}
}
自适应生成的扩展类
package com.city.common.spi;
import org.apache.dubbo.common.extension.ExtensionLoader;
public class IOrderService$Adaptive implements com.city.common.spi.IOrderService {
public java.lang.String pay(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("i.order.service", "alipay");
if(extName == null) throw new IllegalStateException("Failed to get extension (com.city.common.spi.IOrderService) name from url (" + url.toString() + ") use keys([i.order.service])");
com.city.common.spi.IOrderService extension = (com.city.common.spi.IOrderService)ExtensionLoader.getExtensionLoader(com.city.common.spi.IOrderService.class).getExtension(extName);
return extension.pay(arg0);
}
public java.lang.String way() {
throw new UnsupportedOperationException("The method public abstract java.lang.String com.city.common.spi.IOrderService.way() of interface com.city.common.spi.IOrderService is not adaptive method!");
}
}
Wrapper机制
包装目标对象进行增强
public class OrderWrapper implements IOrderService {
private IOrderService order;
public OrderWrapper(IOrderService order) {
this.order = order;
}
@Override
public String way() {
System.out.println("before-设置wrapper对pay()的增强");
String way = order.way();
System.out.println("after-设置wrapper对pay()的增强");
return way;
}
@Override
public String pay(URL url) {
System.out.println("before-设置wrapper对pay()的增强");
String pay = order.pay(url);
System.out.println("after-设置wrapper对pay()的增强");
return pay;
}
}
wrapper=com.city.common.spi.wrapper.OrderWrapper
Activate机制
@Activate的作用就是为当前扩展类添加一个用于帅选的标签
group 属性 与 value 属性的关系为 与