2018-04-03

参考 http://lrd.ele.me/2017/01/09/dynamic_proxy/

jdk 代理

rem target 实例化的对象

--> Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    --> Class<?> cl = getProxyClass0(loader, intfs);  // intfs 对象接口
    重点 :
        --> return proxyClassCache.get(loader, interfaces);  // proxyClassCache 缓存
            -->  Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); // 获取subkey   [KeyFactory类型] subKeyFactory
                --> Supplier<V> supplier = valuesMap.get(subKey); value 域  <ProxyClassFactory> 类型  supplier.apply() == ProxyClassFactory.apply()
                        --> Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
                            //Verify that the class loader resolves the name of this interface to the same Class object.
                            //Verify that the Class object actually represents an interface.
                            //Verify that this interface is not a duplicate.
                        --> interfaceClass = Class.forName(intf.getName(), false, loader);  // 逐个遍历 interfaces  
                        --> long num = nextUniqueNumber.getAndIncrement();
                        --> String proxyName = proxyPkg + proxyClassNamePrefix + num; //生成名称
                        --> byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); // 生成classbyte  [核心]
                        --> return defineClass0(loader, proxyName,  proxyClassFile, 0, proxyClassFile.length); //定义类
                --> factory = new Factory(key, parameter, subKey, valuesMap);// valueFactory 即 valuesMap 中 value 的封装                    
    --> final Constructor<?> cons = cl.getConstructor(constructorParams);
    --> final InvocationHandler ih = h;
    --> return cons.newInstance(new Object[]{h});


生成$Proxy0 class 反编译

static {
    try {
        m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
        m2 = Class.forName("java.lang.Object").getMethod("toString");
        m3 = Class.forName("BookFacade").getMethod("addBook");
        m0 = Class.forName("java.lang.Object").getMethod("hashCode");
    } catch (NoSuchMethodException var2) {
        throw new NoSuchMethodError(var2.getMessage());
    } catch (ClassNotFoundException var3) {
        throw new NoClassDefFoundError(var3.getMessage());
    }
}
生成的方法
  public final void addBook() throws  {
    try {
        super.h.invoke(this, m3, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

jdk proxy的调用是一个反射调用的过程

cglib 动态代理的实现分析

代理类继承自org.springframework.cglib.proxy.MethodInterceptor  实现intercept方法
关键代码 ::     
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(this.target.getClass()); // 将接口直接设置成BookFacadeProxyCglib 实现类
    // 回调方法 
    // enhancer.setCallbackType(this.getClass()); 
    enhancer.setCallback(this);     //设置回调
    // 创建代理对象
    return enhancer.create();  
    --> return this.createHelper(); 
        -->  this.setNamePrefix(this.superclass.getName());设置NamePrefix 
        --> return super.create(KEY_FACTORY.newInstance(this.superclass != null ? this.superclass.getName() : null, ReflectUtils.getNames(this.interfaces), this.filter, this.callbackTypes, this.useFactory, this.interceptDuringConstruction, this.serialVersionUID));

 // 代理产生的几个类

    fastclass        --> public class BookFacadeImpl$$EnhancerByCGLIB$$677aba98$$FastClassByCGLIB$$dcb5b9cc extends FastClass 
    class            --> public class BookFacadeImpl$$EnhancerByCGLIB$$677aba98 extends BookFacadeImpl implements Factory 
    keyFactory       --> public class Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f extends KeyFactory implements EnhancerKey 
    methodwrapperkey --> public class MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$552be97a extends KeyFactory implements MethodWrapperKey  
 
 
 整个aop执行过程 
    [ BookFacadeImpl$$EnhancerByCGLIB$$677aba98 ] addbook 
    --> [ MethodIntercepter.intercept ] 
    < before method exe >
    --> [ BookFacadeImpl$$EnhancerByCGLIB$$677aba98$$FastClassByCGLIB$$dcb5b9cc.invoke ]
    --> [ BookFacadeImpl$$EnhancerByCGLIB$$677aba98.CGLIB$addBook$0  >>>> (final 方法) ]
    --> [ super[BookFacadeImpl].addBook ]
    < after method exe >
    --> [ MethodIntercepter.intercept ] 
   
    调用路径
    //使用的是这个对象
    --> BookFacadeImpl$$EnhancerByCGLIB$$677aba98 
        |    private boolean CGLIB$BOUND;
        |    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;  //threadlocal 中存放callback
        |    private static final Callback[] CGLIB$STATIC_CALLBACKS;   // static callback
        |    private MethodInterceptor CGLIB$CALLBACK_0;               // 用户自己实现的MethodInterceptor
        |    private static final Method CGLIB$addBook$0$Method;       // 父类中的callback 方法
        |    private static final MethodProxy CGLIB$addBook$0$Proxy;   // 方法代理 MethodProxy 类
        |    private static final Object[] CGLIB$emptyArgs;            // 方法参数
        |    private static final Method CGLIB$finalize$1$Method;
        |    private static final MethodProxy CGLIB$finalize$1$Proxy;
        |    private static final Method CGLIB$equals$2$Method;
        |    private static final MethodProxy CGLIB$equals$2$Proxy;
        |    private static final Method CGLIB$toString$3$Method;
        |    private static final MethodProxy CGLIB$toString$3$Proxy;
        |    private static final Method CGLIB$hashCode$4$Method;
        |    private static final MethodProxy CGLIB$hashCode$4$Proxy;
        |    private static final Method CGLIB$clone$5$Method;
        |    private static final MethodProxy CGLIB$clone$5$Proxy;
        |    
        |    static void CGLIB$STATICHOOK1() {
        |        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        |        CGLIB$emptyArgs = new Object[0];
        |        Class var0 = Class.forName("BookFacadeImpl$$EnhancerByCGLIB$$677aba98"); //当前类的实例
        |        Class var1;
        |        Method[] var10000 = ReflectUtils.findMethods(new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        |        CGLIB$finalize$1$Method = var10000[0];
        |        CGLIB$finalize$1$Proxy = MethodProxy.create(var1, var0, "()V", "finalize", "CGLIB$finalize$1");
        |        CGLIB$equals$2$Method = var10000[1];
        |        CGLIB$equals$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
        |        CGLIB$toString$3$Method = var10000[2];
        |        CGLIB$toString$3$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
        |        CGLIB$hashCode$4$Method = var10000[3];
        |        CGLIB$hashCode$4$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$4");
        |        CGLIB$clone$5$Method = var10000[4];
        |        CGLIB$clone$5$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
                 // var1 赋值
        |        CGLIB$addBook$0$Method = ReflectUtils.findMethods(new String[]{"addBook", "()V"}, (var1 = Class.forName("BookFacadeImpl")).getDeclaredMethods())[0];
        |        CGLIB$addBook$0$Proxy = MethodProxy.create(var1, var0, "()V", "addBook", "CGLIB$addBook$0");
        |    }
    --> addBook()
        --> 
            -->| public final void addBook() {
            -->|     MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;//获取当前类中的methodintercepter
            -->|     if (this.CGLIB$CALLBACK_0 == null) {
            -->|         CGLIB$BIND_CALLBACKS(this);                //如果为空
            -->|         var10000 = this.CGLIB$CALLBACK_0;
            -->|     }
            -->| 
            -->|     if (var10000 != null) {
                         // 执行MethodInterceptor 类中的方法 <实现了MethodInterceptor的类> -->  
            -->|         var10000.intercept(this, CGLIB$addBook$0$Method, CGLIB$emptyArgs, CGLIB$addBook$0$Proxy); 
            -->|     } else {
            -->|         super.addBook();
            -->|     }
            -->| }

            -->| private static final void CGLIB$BIND_CALLBACKS(Object var0) {
            -->|     BookFacadeImpl$$EnhancerByCGLIB$$677aba98 var1 = (BookFacadeImpl$$EnhancerByCGLIB$$677aba98)var0;
            -->|     if (!var1.CGLIB$BOUND) {
            -->|         var1.CGLIB$BOUND = true;
            -->|         Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            -->|         if (var10000 == null) {
            -->|             var10000 = CGLIB$STATIC_CALLBACKS;
            -->|             if (CGLIB$STATIC_CALLBACKS == null) {
            -->|                 return;
            -->|             }
            -->|        }
            -->|        
            -->|         var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
            -->|     }
            -->|     
            -->| }

            实现了 MethodInterceptor的类
            -->|>|public class BookFacadeProxyCglib implements MethodInterceptor {
            -->|>|    private Object target;
            -->|>|
            -->|>|    public Object getInstance(Object target) {
            -->|>|        this.target = target;
            -->|>|        Enhancer enhancer = new Enhancer();
            -->|>|        enhancer.setSuperclass(this.target.getClass());
            -->|>|        // 回调方法
            -->|>|        // enhancer.setCallbackType(this.getClass());
            -->|>|        enhancer.setCallback(this);
            -->|>|        // 创建代理对象
            -->|>|        return enhancer.create();
            -->|>|    }
            -->|>|    
            -->|>|    @Override
            -->|>|    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            -->|>|        System.out.println("before run!");
                          // 执行MethodProxy的invokeSuper
            -->|>|        proxy.invokeSuper(obj, args);
            -->|>|        System.out.println("after run!");
            -->|>|        return null;
            -->|>|    }
            -->|>|}

            MethodProxy的invokeSuper 方法
            -->| public Object invokeSuper(Object obj, Object[] args) throws Throwable {
            -->|     try {
            -->|         this.init();

                        ------> | private void init() {
                        ------> |     if (this.fastClassInfo == null) {
                        ------> |         Object var1 = this.initLock;
                        ------> |         synchronized(this.initLock) {
                        ------> |             if (this.fastClassInfo == null) {
                        ------> |                 MethodProxy.CreateInfo ci = this.createInfo;
                        ----------------------- 对应  --> CGLIB$addBook$0$Proxy = MethodProxy.create(var1, var0, "()V", "addBook", "CGLIB$addBook$0");
                        MethodProxy 中的变量赋值
                        [ c1 = var1 = BookFacadeImpl                            ]  
                        [ c2 = var0 = BookFacadeImpl$$EnhancerByCGLIB$$677aba98 ]
                        [ name1 = addBook         = new Signature(name1, desc); ]
                        [ name2 = CGLIB$addBook$0 = new Signature(name2, desc); ]
                                            --> | public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
                                            --> |     MethodProxy proxy = new MethodProxy();
                                            --> |     proxy.sig1 = new Signature(name1, desc);
                                            --> |     proxy.sig2 = new Signature(name2, desc);
                                            --> |     proxy.createInfo = new MethodProxy.CreateInfo(c1, c2);
                                            --> |     return proxy;
                                            --> | }
                        -----------------------
                        ------> |                 MethodProxy.FastClassInfo fci = new MethodProxy.FastClassInfo(); //实例化FastClassInfo
                        ------> |                 fci.f1 = helper(ci, ci.c1);
                        ----------------------------------------------------------------------------------------------------------------------
                                                    ---->| private static FastClass helper(MethodProxy.CreateInfo ci, Class type) {
                                                    ---->|    Generator g = new Generator();
                                                    ---->|    g.setType(type);
                                                    ---->|    g.setClassLoader(ci.c2.getClassLoader());
                                                    ---->|    g.setNamingPolicy(ci.namingPolicy);
                                                    ---->|    g.setStrategy(ci.strategy);
                                                    ---->|    g.setAttemptLoad(ci.attemptLoad);
                                                    ---->|    return g.create();
                                                             >| org.springframework.cglib.core.AbstractClassGenerator#create //最终调用AbstractClassGenerator的create方法
                                                    ---->|   }
                        ----------------------------------------------------------------------------------------------------------------------
                        ------> |                 fci.f2 = helper(ci, ci.c2);
                        ------> |                 fci.i1 = fci.f1.getIndex(this.sig1);
                        ------> |                 fci.i2 = fci.f2.getIndex(this.sig2);
                        ------> |                 this.fastClassInfo = fci;
                        ------> |                 this.createInfo = null;
                        ------> |             }
                        ------> |         }
                        ------> |     }
                        ------> | }
            -->|         MethodProxy.FastClassInfo fci = this.fastClassInfo;
            -->|         return fci.f2.invoke(fci.i2, obj, args);
            -->|     } catch (InvocationTargetException var4) {
            -->|         throw var4.getTargetException();
            -->|     }
            -->| }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容