SOFABoot源码解析之JVM服务代理机制

1.SOFABoot源码解析

1.1  JVM服务代理机制

        在SOFABoot中,采用AOP代理方式为JVM服务引用创建本地代理对象。对于AOP代理,主要有两种实现方式:

        1.   针对实现接口的类,采用JDK动态代理机制;

        2.   针对没有实现接口的类,采用CGLIB动态代理机制;

        在SOFABoot中,对于JVM服务类型的服务引用,即可以针对某个接口创建代理对象,也可以针对某个类创建代理对象。

1.1.1 AOP代理之JDK动态代理

        针对接口(例如:com.alipay.sofa.boot.examples.demo.rpc.bean.PersonService接口),为其创建JVM服务的AOP代理对象的主要逻辑如下:

        1.   创建handler,此处为ServiceProxy抽象类的子类JvmServiceInvoker的实例。该类继承了ServiceProxy,而ServiceProxy实现了org.aopalliance.intercept.MethodInterceptor接口,表示此处创建AOP代理的方法拦截器。该AOP代理拦截器拦截对proxyClass指定的接口(例如: PersonService)的方法调用。

        2.   创建AOP代理工厂类org.springframework.aop.framework.ProxyFactory的实例factory;

        3.   配置factory:如果javaClass为接口,则factory的interfaces列表中增加javaClass。否则,设置factory的targetClass为javaClass,proxyTarget为true。

        4.   把指定的AOP advice实例handler增加到advice链尾部。

        5.   调用factory的getProxy方法,为指定服务创建AOP代理对象。由于此处目标类是接口,则使用JDK动态代理技术。Spring使用JDK来生成代理对象,具体的实现代码放在org.springframework.aop.framework.JdkDynamicAopProxy这个类中。JdkDynamicAopProxy 同时实现了AopProxy和InvocationHandler接口,InvocationHandler是JDK动态代理的核心,生成的代理对象的方法调用都会委托到InvocationHandler.invoke()方法。invoke主流程可以简述为:获取可以应用到此方法上的通知链(InterceptorChain),如果有,则应用通知,并执行joinpoint;如果通知链为空,则直接反射执行joinpoint。

        以上是使用JDK动态代理机制动态创建JVM服务的AOP代理对象的主要流程。

        为了查看Proxy动态生成的代理对象的源文件,必须先导出字节码文件,然后通过反编译工具(如:jad)生成源文件。对于Proxy,导出字节码文件方式为在应用代码开始位置设置sun.misc.ProxyGenerator.saveGeneratedFiles为true:

1.  @SpringBootApplication
2.  @ImportResource({"classpath*:rpc-starter-example.xml" })
3.  public class SofaBootRpcDemoApplication {
4.   
5.      public static void main(String[] args)throws InterruptedException {
6.       
7.        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
8.       
9.        ConfigurableApplicationContext ac =SpringApplication.run(SofaBootRpcDemoApplication.class, args);
10.          
11.  
12.     }
13. }

        注意,需要在工程根目录下,增加 com/sun/proxy目录,否则会报错如下:

1.  Exception in thread "main"java.lang.InternalError: I/O exception saving generatedfile:java.io.FileNotFoundException : com\sun\proxy\$Proxy0.class (系统找不到指定的路径。)
2.       atsun.misc.ProxyGenerator$1.run(ProxyGenerator.java:336 )
3.       atsun.misc.ProxyGenerator$1.run(ProxyGenerator.java:327 )
4.       atjava.security.AccessController.doPrivileged( Native Method)
5.       atsun.misc.ProxyGenerator.generateProxyClass( ProxyGenerator.java:326)
6.       atjava.lang.reflect.Proxy$ProxyClassFactory.apply( Proxy.java:672)
7.       atjava.lang.reflect.Proxy$ProxyClassFactory.apply( Proxy.java:592)
8.       atjava.lang.reflect.WeakCache$Factory.get( WeakCache.java:244)
9.       atjava.lang.reflect.WeakCache.get(WeakCache.java:141 )
10.      at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:455 )
11.      atjava.lang.reflect.Proxy.newProxyInstance( Proxy.java:738)

        以下为PersonService接口的AOP代理对象的源文件:

1.  package com.sun.proxy;
2.   
3.  importcom.alipay.sofa.boot.examples.demo.rpc.bean.PersonService;
4.  import java.lang.reflect.InvocationHandler;
5.  import java.lang.reflect.Method;
6.  import java.lang.reflect.Proxy;
7.  importjava.lang.reflect.UndeclaredThrowableException;
8.  import org.aopalliance.aop.Advice;
9.  import org.springframework.aop.Advisor;
10. import org.springframework.aop.SpringProxy;
11. importorg.springframework.aop.TargetSource;
12. importorg.springframework.aop.framework.Advised;
13. importorg.springframework.aop.framework.AopConfigException;
14. importorg.springframework.core.DecoratingProxy;
15.  
16. public final class $Proxy50 extends Proxy
17.   implementsPersonService, SpringProxy, Advised, DecoratingProxy
18. {
19.   private static Method m19;
20.   private static Method m15;
21.   private static Method m27;
22.   private static Method m6;
23.   private static Method m2;
24.   private static Method m25;
25.   private static Method m24;
26.   private static Method m11;
27.   private static Method m4;
28.   private static Method m26;
29.   private static Method m8;
30.   private static Method m22;
31.   private static Method m20;
32.   private static Method m21;
33.   private static Method m16;
34.   private static Method m9;
35.   private static Method m23;
36.   private static Method m5;
37.   private static Method m12;
38.   private static Method m13;
39.   private static Method m1;
40.   private static Method m18;
41.   private static Method m10;
42.   private static Method m17;
43.   private static Method m3;
44.   private static Method m0;
45.   private static Method m7;
46.   private static Method m14;
47.  
48.   public $Proxy50(InvocationHandlerparamInvocationHandler)
49.     throws
50.   {
51.     super(paramInvocationHandler);
52.   }
53.  
54.   public final boolean isPreFiltered()
55.     throws
56.   {
57.     try
58.     {
59.       return ((Boolean)this.h.invoke(this, m19,null)).booleanValue();
60.     }
61.     catch (RuntimeExceptionlocalRuntimeException)
62.     {
63.       throw localRuntimeException;
64.     }
65.     catch (Throwable localThrowable)
66.     {
67.     }
68.     throw newUndeclaredThrowableException(localThrowable);
69.   }
70.  
71.   public final boolean isProxyTargetClass()
72.     throws
73.   {
74.     try
75.     {
76.       return ((Boolean)this.h.invoke(this, m15,null)).booleanValue();
77.     }
78.     catch (RuntimeException localRuntimeException)
79.     {
80.       throw localRuntimeException;
81.     }
82.     catch (Throwable localThrowable)
83.     {
84.     }
85.     throw newUndeclaredThrowableException(localThrowable);
86.   }
87.  
88.   public final Class getDecoratedClass()
89.     throws
90.   {
91.     try
92.     {
93.       return (Class)this.h.invoke(this, m27,null);
94.     }
95.     catch (RuntimeExceptionlocalRuntimeException)
96.     {
97.       throw localRuntimeException;
98.     }
99.     catch (Throwable localThrowable)
100.     {
101.     }
102.     throw newUndeclaredThrowableException(localThrowable);
103.   }
104.  
105.   public final boolean isFrozen()
106.     throws
107.   {
108.     try
109.     {
110.       return ((Boolean)this.h.invoke(this, m6,null)).booleanValue();
111.     }
112.     catch (RuntimeExceptionlocalRuntimeException)
113.     {
114.       throw localRuntimeException;
115.     }
116.     catch (Throwable localThrowable)
117.     {
118.     }
119.     throw newUndeclaredThrowableException(localThrowable);
120.   }
121.  
122.   public final String toString()
123.     throws
124.   {
125.     try
126.     {
127.       return (String)this.h.invoke(this, m2,null);
128.     }
129.     catch (RuntimeException localRuntimeException)
130.     {
131.       throw localRuntimeException;
132.     }
133.     catch (Throwable localThrowable)
134.     {
135.     }
136.     throw newUndeclaredThrowableException(localThrowable);
137.   }
138.  
139.   public final boolean removeAdvice(AdviceparamAdvice)
140.     throws
141.   {
142.     try
143.     {
144.       return ((Boolean)this.h.invoke(this, m25,new Object[] { paramAdvice })).booleanValue();
145.     }
146.     catch (RuntimeExceptionlocalRuntimeException)
147.     {
148.       throw localRuntimeException;
149.     }
150.     catch (Throwable localThrowable)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

任性之闲来无事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值