Wrapper机制,即扩展类的包装机制;就是对扩展类中的SPI接口方法进行增强,进行包装,是AOP思想的提现,是Wrapper(装饰者)设计模式的应用(是一种特例的装饰者设计模式),一个SPI可以包含多个Wrapper。
注意,Wrapper类不属于“拓展类”;
1.Wrapper类规范
Wrapper机制不是通过注解实现的,而是通过Wrapper类实现,Wrapper类在定义时需要遵循如下规范:
-
类要实现SPI接口;
-
类中要有SPI接口的引用;
-
在接口实现方法中要调用SPI接口引用对象的相应方法;
-
类名称一般以Wrapper结尾(规范约定,非必须)
2.源码示例
filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=org.apache.dubbo.rpc.support.MockProtocol
//################Protocol#######################
package org.apache.dubbo.rpc;
import ***
/**
* Protocol. (API/SPI, Singleton, ThreadSafe)
*/
@SPI("dubbo")
public interface Protocol {
int getDefaultPort();
//*@Adaptive修饰的方法,会生成扩展类
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
//*@Adaptive修饰的方法,会生成扩展类
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
void destroy();
default List<ProtocolServer> getServers() {
return Collections.emptyList();
}
}
//##############ProtocolFilterWrapper#############
package org.apache.dubbo.rpc.protocol;
import ***
/**
* ListenerProtocol
*/
@Activate(order = 100)
//1-实现Protocol接口,即实现一个SPI接口
public class ProtocolFilterWrapper implements Protocol {
//2-包含Protocol的引用
private final Protocol protocol;
public ProtocolFilterWrapper(Protocol protocol) {
if (protocol == null) {
throw new IllegalArgumentException("protocol == null");
}
this.protocol = protocol;
}
private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
...
}
@Override
public int getDefaultPort() {
//3-实现方法中调用引用的方法
return protocol.getDefaultPort();
}
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
if (UrlUtils.isRegistry(invoker.getUrl())) {
return protocol.export(invoker);
}
//增强引用方法,此为Wrapper装饰者模式的主要目的
return protocol.export(buildInvokerChain(invoker, SERVICE_FILTER_KEY, CommonConstants.PROVIDER));
}
@Override
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
if (UrlUtils.isRegistry(url)) {
return protocol.refer(type, url);
}
return buildInvokerChain(protocol.refer(type, url), REFERENCE_FILTER_KEY, CommonConstants.CONSUMER);
}
@Override
public void destroy() {
protocol.destroy();
}
@Override
public List<ProtocolServer> getServers() {
return protocol.getServers();
}
}
3.示例代码
(1)创建工程wapper导入dubbo依赖
<!-- dubbo依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.0</version>
</dependency>
(2)创建提供者路径及配置文件
alipay=com.zxy.spi.extension.AlipayOrder
wechat=com.zxy.spi.extension.WeChatOrder
wrapper=com.zxy.spi.extension.OrderWrapper
wrapper2=com.zxy.spi.extension.OrderWrapper2
(3)创建接口及实现类
/**
* SPI标签,设置默认为alipay阿里支付
*/
@SPI("alipay")
public interface Order {
//支付方式
String way();
//支付
@Adaptive
String pay(URL url);
}
//###################################################
public class AlipayOrder implements Order{
public String way() {
System.out.println("---支付宝way()---");
return "支付宝支付方式";
}
@Override
public String pay(URL url) {
System.out.println("---支付宝pay()---");
return "使用支付宝支付";
}
}
//###################################################
public class WeChatOrder implements Order{
public String way() {
System.out.println("---微信way()---");
return "微信支付方式";
}
@Override
public String pay(URL url) {
System.out.println("---微信pay()---");
return "使用微信支付";
}
}
//###################################################
public class OrderWrapper implements Order{
private Order order;
public OrderWrapper(Order order) {
this.order = order;
}
@Override
public String way() {
System.out.println("before-这是wrapper对way()方法的增强!");
String way = order.way();
System.out.println("after-这是wrapper对way()方法的增强!");
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;
}
}
//###################################################
public class OrderWrapper2 implements Order{
private Order order;
public OrderWrapper2(Order order) {
this.order = order;
}
@Override
public String way() {
System.out.println("22222before-这是wrapper对way()方法的增强!");
String way = order.way();
System.out.println("22222after-这是wrapper对way()方法的增强!");
return way;
}
@Override
public String pay(URL url) {
System.out.println("22222before-这是wrapper对pay()方法的增强!");
String pay = order.pay(url);
System.out.println("22222after-这是wrapper对pay()方法的增强!");
return pay;
}
}
(4)定义测试启动类
public class OrderTest {
public static void main(String[] args) {
ExtensionLoader<Order> loader = ExtensionLoader.getExtensionLoader(Order.class);
// 获取自适应AdaptiveExtension
Order adaptiveExtension = loader.getAdaptiveExtension();
//模拟一个URL,不指定支付方式使用默认
URL url = URL.valueOf("xxx://localhost/ooo");
System.out.println(adaptiveExtension.pay(url));
}
}
(5)运行结果
结果中输出顺序说明,先运行外部增强OrderWapper2,然后执行内部增强OrderWapper,此运行顺序是由META-INF中的order注册文件决定,执行顺序是倒序执行;
4.Wrapper作用(重要)
注意,Wrapper不属于扩展类,如示例代码中的OrderWapper并不是order接口的扩展类,真正的扩展类是AlipayOrder及WeChatOrder,而OrderWapper作用是辅助增强扩展类AlipayOrder和WeChatOrder的功能,OrderWapper不可以单独使用;
(1)通过代码验证OrderWapper不是扩展类
public class OrderTest {
public static void main(String[] args) {
ExtensionLoader<Order> loader = ExtensionLoader.getExtensionLoader(Order.class);
//通过loader.getSupportedExtensions()获取order接口所有的拓展类名
Set<String> extensions = loader.getSupportedExtensions();
System.out.println(extensions);
}
}
注意:由@Adaptive修饰的类同样也不是扩展类,其也不能单独使用。