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修饰的类同样也不是扩展类,其也不能单独使用。