1. 程式人生 > >淺談Java代理二:Cglib動態代理-MethodInterceptor

淺談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