SpringAOP CGLIB動態代理 理解

今天貼出來自己關於spring cglib動態代理的一些理解。小二,先上代碼

package com.suning.sample.aop;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibTest {
    /**
     * CGLIB動態代理測試類: <br>
     * 〈功能詳細描述〉
     *
     * @param args
     * @see [相關類/方法](可選)
     * @since [產品/模塊版本](可選)
     */
    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        TargetClass proxyClass = (TargetClass)proxy.getProxy(TargetClass.class);
        proxyClass.removeTopic(11);
    }

}

//目標類
class TargetClass{
    public void removeTopic(int topicld){
        System.out.println("這裏執行目標對象代碼");
    }
}

//創建cglib代理類
class CglibProxy implements MethodInterceptor{

    private Enhancer enhancer = new Enhancer();
    
    public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("嗨,我開始織入代碼");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("結束織入標示");
        return result;
    }
    
}



1.通過getProxy()方法以及反射機制創建目標類TargetClass的動態代理對象,

public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
getProxy()指定了代理對象爲目標類TargetClass的子類,即proxyClass爲TargetClass類的代理類對象。


2.當目標類TargetClass執行removeTopic()方法時,就相當於代理類執行removeTopic()方法。原因:

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("嗨,我開始織入代碼");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("結束織入標示");
        return result;
    }
代理類會攔截所有父類對象方法的調用,在攔截裏面,會植入增強代碼,其中intercept爲CGLIB的Interceptor接口定義的方法,筆者認爲這是實現增強的關鍵,這裏也相當於是切點入口了。這裏研究下intercept參數:

obj:   com.suning.sample.aop.TargetClass$$EnhancerByCGLIB$$e0c2e315@8ee016

method:   public void com.suning.sample.aop.TargetClass.removeTopic(int)

args:  11

proxy: net.sf.cglib.proxy.MethodProxy@5a67c9

obj是CGLIB創建的目標類的子類,method爲目標類調用方法,args爲方法傳參,proxy爲代理類實例。這裏有個小疑惑,obj和proxy有啥區別呢?求大神解答。


3.運行結果




使用心得:

1.CGLIB是通過建立目標類的子類代理對象,從而執行代碼嵌入的;區別於JDK的通過接口代理。











發佈了45 篇原創文章 · 獲贊 3 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章