我是靠谱客的博主 凶狠冰淇淋,这篇文章主要介绍Dubbo源码阅读六:Dubbo动态生成的类第1节 Dubbo动态生成的类第2节 Protocol$Adaptive类第3节 ProxyFactory$Adaptive类第4节 ProxyFactory Extension实例第5节 Wrapper子类第六节 Protocol Extension实例第七节 Filter Active Extension实例,现在分享给大家,希望可以做个参考。

第1节 Dubbo动态生成的类

dubbo在调用exportServices()方法时,会使用代码生成技术动态地生成Protocol$Adaptive、ProxyFactory$Adaptive和Wrapper子类这些类。

Dubbo使用javassist动态生成类。Dubbo有两个场景使用动态类。

1)ExtensionLoader.getExtensionLoader().getAdaptiveExtension()使用JavassistCompiler生成每个类型的Adaptive类。Protocol$Adaptive、ProxyFactory$Adaptive等类通过这种方法生成。

2)ServiceConfig.doExportUrlsFor1Protocol()使用JavassistProxyFactory.getInvoker()方法调用Wrapper.makeWrapper()方法,为xml中的<dubbo:service>生成Wrapper子类。

第2节 Protocol$Adaptive类

GreetingService的定义如下。

复制代码
1
2
3
4
5
package org.example.dubbo2.provider.api; public interface GreetingService { String sayHi(String name); String sayBye(String name); }

GreetingServiceImpl的实现如下。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package org.example.dubbe2.provider.impl; import org.example.dubbo2.provider.api.GreetingService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GreetingServiceImpl implements GreetingService { private static final Logger logger = LoggerFactory.getLogger(GreetingServiceImpl.class); @Override public String sayHi(String name) { logger.info(name); return "hi, " + name; } @Override public String sayBye(String name) { logger.info(name); return "bye, " + name; } }

启动类如下。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package org.example.dubbe2.provider.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; @Configuration public class Dubbo2ProviderApplication { private static final Logger logger = LoggerFactory.getLogger(Dubbo2ProviderApplication.class); public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"/spring/dubbo-provider.xml"}); context.start(); System.in.read(); // 按任意键退出 } }

dubbo-provider.xml内容如下。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubbo2-provider"/> <dubbo:registry address="zookeeper://172.16.4.126:2181"/> <dubbo:metadata-report address="zookeeper://172.16.4.126:2181"/> <dubbo:protocol name="dubbo" port="20880"/> <dubbo:service interface="org.example.dubbo2.provider.api.GreetingService" ref="greetingService"/> <bean id="greetingService" class="org.example.dubbe2.provider.impl.GreetingServiceImpl"/> </beans>

ServiceConfig的定义如下(去掉了其他信息)。JVM在加载ServiceConfig类时,会初始化他的两个static静态字段。

复制代码
1
2
3
4
public class ServiceConfig<T> extends ServiceConfigBase<T> { private static final Protocol PROTOCOL = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); private static final ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); }

在调用ExtensionLoader.getAdaptiveExtension()方法时,会执行createAdaptiveExtensionClass()方法动态生成Protocol$Adaptive和ProxyFactoryAdaptive类。在createAdaptiveExtensionClass()代码中增加断点,启动程序执行到断点处,查看code的值,如下图所示。

将code的值拷贝出来格式化后,动态生成的Protocol$Adaptive类代码如下。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package org.apache.dubbo.rpc; import org.apache.dubbo.common.extension.ExtensionLoader; public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol { public void destroy() { throw new UnsupportedOperationException("The method public abstract void org.apache.dubbo.rpc.Protocol.destroy() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!"); } public int getDefaultPort() { throw new UnsupportedOperationException("The method public abstract int org.apache.dubbo.rpc.Protocol.getDefaultPort() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!"); } public org.apache.dubbo.rpc.Invoker refer(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) throws org.apache.dubbo.rpc.RpcException { if (arg1 == null) throw new IllegalArgumentException("url == null"); org.apache.dubbo.common.URL url = arg1; String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol()); if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])"); org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName); return extension.refer(arg0, arg1); } public org.apache.dubbo.rpc.Exporter export(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException { if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null"); if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null"); org.apache.dubbo.common.URL url = arg0.getUrl(); String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol()); if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])"); org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName); return extension.export(arg0); } public java.util.List getServers() { throw new UnsupportedOperationException("The method public default java.util.List org.apache.dubbo.rpc.Protocol.getServers() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!"); } }

 

第3节 ProxyFactory$Adaptive类

将code的值拷贝出来格式化后,动态生成的ProxyFactory$Adaptive类代码如下。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package org.apache.dubbo.rpc; import org.apache.dubbo.common.extension.ExtensionLoader; public class ProxyFactory$Adaptive implements org.apache.dubbo.rpc.ProxyFactory { public org.apache.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1, org.apache.dubbo.common.URL arg2) throws org.apache.dubbo.rpc.RpcException { if (arg2 == null) throw new IllegalArgumentException("url == null"); org.apache.dubbo.common.URL url = arg2; String extName = url.getParameter("proxy", "javassist"); if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.ProxyFactory) name from url (" + url.toString() + ") use keys([proxy])"); org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName); return extension.getInvoker(arg0, arg1, arg2); } public java.lang.Object getProxy(org.apache.dubbo.rpc.Invoker arg0, boolean arg1) throws org.apache.dubbo.rpc.RpcException { if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null"); if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null"); org.apache.dubbo.common.URL url = arg0.getUrl(); String extName = url.getParameter("proxy", "javassist"); if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.ProxyFactory) name from url (" + url.toString() + ") use keys([proxy])"); org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName); return extension.getProxy(arg0, arg1); } public java.lang.Object getProxy(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException { if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null"); if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null"); org.apache.dubbo.common.URL url = arg0.getUrl(); String extName = url.getParameter("proxy", "javassist"); if (extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.ProxyFactory) name from url (" + url.toString() + ") use keys([proxy])"); org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory) ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName); return extension.getProxy(arg0); } }

第4节 ProxyFactory Extension实例

org.apache.dubbo.rpc.ProxyFactory配置内容如下:

复制代码
1
2
3
stub=org.apache.dubbo.rpc.proxy.wrapper.StubProxyFactoryWrapper jdk=org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory javassist=org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory

这些类都实现了ProxyFacotry接口。

ProxyFactory类的ExtesnionLoader加载器在实例化JavassistProxyFactory对象时,会对JavassistProxyProxyFactory实例加上StubProxyFactoryWrapper装饰,其目的是利用装饰器模式来实现AOP的功能。

第5节 Wrapper子类

在ServiceConfig.doExportUrlsFor1Protocol()方法中调用exportLocal()处增加断点如下图,启动程序执行到这里,然后F7执行进入exportLocal()方法。

执行到PROTOCOL.export(PROXY_FACTORY.getInvoker(ref, interfaceClass, local))。

 

然后F7调用进入JavassistProxFactory.getInvoker()方法。一直往下执行到Wrapper.makeWrapper()方法。

 

在Wrapper.makeWrapper()方法中的cc.toClass()增加断点,运行到此处,然后F7进入ClassGenerator.toClass()方法,接着进入ClassGenerator.toClass(ClassLoader loader, ProtectionDomain pd)方法,一直F8单步运行到return mCtc.toClass(laoder, pd)。

 

 

 

在IDEA中点开Evaluate对话框,在Expression编辑框中输入如下代码,将动态生成的CtClass对象写入本地1.class文件中。

复制代码
1
FileOutputStream out1 = new FileOutputStream("D:\1.class");out1.write(mCtc.toBytecode());out1.close();return "";

 然后找到这个1.class文件,选中后拖入IDEA编辑框,就可以查看到class文件对应的源码内容。

复制代码
1
2
<dubbo:service interface="org.example.dubbo2.provider.api.GreetingService" ref="greetingService"/> <bean id="greetingService" class="org.example.dubbe2.provider.impl.GreetingServiceImpl"/>

 为xml中以上<dubbo:service>标签生成的动态类如下,是Wrapper类的子类。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package org.apache.dubbo.common.bytecode; import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.apache.dubbo.common.bytecode.ClassGenerator.DC; import org.example.dubbe2.provider.impl.GreetingServiceImpl; public class Wrapper1 extends Wrapper implements DC { public static String[] pns; public static Map pts; public static String[] mns; public static String[] dmns; public static Class[] mts0; public static Class[] mts1; public String[] getPropertyNames() { return pns; } public boolean hasProperty(String var1) { return pts.containsKey(var1); } public Class getPropertyType(String var1) { return (Class)pts.get(var1); } public String[] getMethodNames() { return mns; } public String[] getDeclaredMethodNames() { return dmns; } public void setPropertyValue(Object var1, String var2, Object var3) { try { GreetingServiceImpl var4 = (GreetingServiceImpl)var1; } catch (Throwable var6) { throw new IllegalArgumentException(var6); } throw new NoSuchPropertyException("Not found property "" + var2 + "" field or setter method in class org.example.dubbe2.provider.impl.GreetingServiceImpl."); } public Object getPropertyValue(Object var1, String var2) { try { GreetingServiceImpl var3 = (GreetingServiceImpl)var1; } catch (Throwable var5) { throw new IllegalArgumentException(var5); } throw new NoSuchPropertyException("Not found property "" + var2 + "" field or getter method in class org.example.dubbe2.provider.impl.GreetingServiceImpl."); } public Object invokeMethod(Object var1, String var2, Class[] var3, Object[] var4) throws InvocationTargetException { GreetingServiceImpl var5; try { var5 = (GreetingServiceImpl)var1; } catch (Throwable var8) { throw new IllegalArgumentException(var8); } try { if ("sayHi".equals(var2) && var3.length == 1) { return var5.sayHi((String)var4[0]); } if ("sayBye".equals(var2) && var3.length == 1) { return var5.sayBye((String)var4[0]); } } catch (Throwable var9) { throw new InvocationTargetException(var9); } throw new NoSuchMethodException("Not found method "" + var2 + "" in class org.example.dubbe2.provider.impl.GreetingServiceImpl."); } public Wrapper1() { } }

第六节 Protocol Extension实例

org.apache.dubbo.rpc.Protocol配置内容如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper mock=org.apache.dubbo.rpc.support.MockProtocol dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol injvm=org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol http=org.apache.dubbo.rpc.protocol.http.HttpProtocol rmi=org.apache.dubbo.rpc.protocol.rmi.RmiProtocol hessian=org.apache.dubbo.rpc.protocol.hessian.HessianProtocol webservice=org.apache.dubbo.rpc.protocol.webservice.WebServiceProtocol thrift=org.apache.dubbo.rpc.protocol.thrift.ThriftProtocol native-thrift=org.apache.dubbo.rpc.protocol.nativethrift.ThriftProtocol memcached=org.apache.dubbo.rpc.protocol.memcached.MemcachedProtocol redis=org.apache.dubbo.rpc.protocol.redis.RedisProtocol rest=org.apache.dubbo.rpc.protocol.rest.RestProtocol xmlrpc=org.apache.dubbo.xml.rpc.protocol.xmlrpc.XmlRpcProtocol grpc=org.apache.dubbo.rpc.protocol.grpc.GrpcProtocol registry=org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol service-discovery-registry=org.apache.dubbo.registry.integration.RegistryProtocol qos=org.apache.dubbo.qos.protocol.QosProtocolWrapper

 这些类都实现了Protocol接口。

ProtocolFilterWrapper、ProtocolListenerWrapper、QosProtocolWrapper是三个装饰器类,用于装饰其他Protocol实例。装饰顺序如下

复制代码
1
2
3
4
QosProtocolWrapper -> ProtocolFilterWrapper -> ProtocolListenerWrapper -> 其他Protocol实现类

第七节 Filter Active Extension实例

org.apache.dubbo.rpc.Filter配置内容如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cache=org.apache.dubbo.cache.filter.CacheFilter validation=org.apache.dubbo.validation.filter.ValidationFilter echo=org.apache.dubbo.rpc.filter.EchoFilter generic=org.apache.dubbo.rpc.filter.GenericFilter genericimpl=org.apache.dubbo.rpc.filter.GenericImplFilter token=org.apache.dubbo.rpc.filter.TokenFilter accesslog=org.apache.dubbo.rpc.filter.AccessLogFilter activelimit=org.apache.dubbo.rpc.filter.ActiveLimitFilter classloader=org.apache.dubbo.rpc.filter.ClassLoaderFilter context=org.apache.dubbo.rpc.filter.ContextFilter consumercontext=org.apache.dubbo.rpc.filter.ConsumerContextFilter exception=org.apache.dubbo.rpc.filter.ExceptionFilter executelimit=org.apache.dubbo.rpc.filter.ExecuteLimitFilter deprecated=org.apache.dubbo.rpc.filter.DeprecatedFilter compatible=org.apache.dubbo.rpc.filter.CompatibleFilter timeout=org.apache.dubbo.rpc.filter.TimeoutFilter tps=org.apache.dubbo.rpc.filter.TpsLimitFilter trace=org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter future=org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter monitor=org.apache.dubbo.monitor.support.MonitorFilter metrics=org.apache.dubbo.monitor.dubbo.MetricsFilter

provider端的Active Filter实例

ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), "service.filter", "provicer")获取到的provider端的有效Filter实例如下:

复制代码
1
2
3
4
5
6
7
8
9
filters = {ArrayList@4255} size = 8 0 = {EchoFilter@5306} 1 = {ClassLoaderFilter@5307} 2 = {GenericFilter@5308} 3 = {ContextFilter@5309} 4 = {TraceFilter@5310} 5 = {TimeoutFilter@5311} 6 = {MonitorFilter@5312} 7 = {ExceptionFilter@5313}

 对invoker进行过滤器链包装,FilterNode链如下图所示

 

最后

以上就是凶狠冰淇淋最近收集整理的关于Dubbo源码阅读六:Dubbo动态生成的类第1节 Dubbo动态生成的类第2节 Protocol$Adaptive类第3节 ProxyFactory$Adaptive类第4节 ProxyFactory Extension实例第5节 Wrapper子类第六节 Protocol Extension实例第七节 Filter Active Extension实例的全部内容,更多相关Dubbo源码阅读六:Dubbo动态生成的类第1节内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(121)

评论列表共有 0 条评论

立即
投稿
返回
顶部