淺談Java代理二:Cglib動態代理-MethodInterceptor


 淺談Java代理二:Cglib動態代理-MethodInterceptor

 

CGLib動態代理特點

使用CGLib實現動態代理,完全不受代理類必須實現接口的限制,而且CGLib底層采用ASM字節碼生成框架,使用字節碼技術生成代理類,比使用Java反射效率要高。唯一需要注意的是,CGLib不能對聲明為final的方法進行代理,因為CGLib原理是動態生成被代理類的子類。

 

 

示例業務邏輯:

1-有一個明星叫胡歌(class HuGe)

3-找明星做事情需要經過助理(ProxyFactory )

4-如果要找胡歌唱歌、演戲,需要先找助理,然后助理去找胡歌唱歌、演戲(class testProcyFactory)

 

 

 

1-被代理類(沒有實現任何接口)

package com.huishe.testOfSpring.methodinterceptor;

public class HuGe {

    public void sing(String song) {
        System.out.println("胡歌演唱: " + song);
    }

    public String act(String teleplay) {
        System.out.println("胡歌決定出演電視劇: " + teleplay);
        return "胡歌答應出演電視劇: " + teleplay;
    }
}

2-代理工廠(即創建代理的通用寫法)

package com.huishe.testOfSpring.methodinterceptor;

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 ProxyFactory implements MethodInterceptor{
    //要代理的原始對象
    private Object object;
    
    //1-創建代理對象
    public Object createProcy(Object target){
        this.object = target;
        //1-Enhancer類是CGLib中的一個字節碼增強器,它可以方便的對你想要處理的類進行擴展
        Enhancer enhancer=new Enhancer();  
        //2-將被代理類HuGe設置成父類
        enhancer.setSuperclass(this.object.getClass());  
        //3-設置攔截器
        enhancer.setCallback(this);  
        //4-動態生成一個代理類
        Object objProxy = enhancer.create();  
        
        return objProxy;
        
    }
    
    //2-實現MethodInterceptor的intercept方法
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("before: " + method);
        //調用proxy.invoke()方法,會報java.lang.StackOverflowError錯誤,原因是invoke()內部會一直被反復調用
        //Object object = proxy.invoke(obj, args);
        Object object = proxy.invokeSuper(obj, args);
        System.out.println("after: " + method);
        return object;
    }
}

 3-進行測試

package com.huishe.testOfSpring.methodinterceptor;

import org.junit.Test;

import net.sf.cglib.proxy.Enhancer;

public class cglibMethodInterceptorTest {

    @Test
    public void testProcyFactory(){
        //1-實例化需要被代理的類
        HuGe huGe = new HuGe();
        //2-實例化代理工廠
        ProxyFactory cglibProxy = new ProxyFactory();
        //3-動態生成一個代理類,並從Object強制轉型成父類型HuGe
        HuGe hg =(HuGe)cglibProxy.createProcy(huGe);
        
        //4-執行動態代理類的方法
        hg.sing("逍遙嘆");
        hg.act("琅琊榜");
        
    }
    
}

 4-測試結果

日志輸出:

before: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
胡歌演唱: 逍遙嘆
after: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
before: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)
胡歌決定出演電視劇: 琅琊榜
after: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)

 

 

參考資料

1-https://blog.csdn.net/jiaotuwoaini/article/details/51675684
2-https://www.cnblogs.com/writeLessDoMore/p/6973853.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM