java動態代理

cglib代理

cglib代理主要通過對字節碼的操作,爲對象引入間接級別,以控制對象的訪問。我們知道Java中有一個動態代理也是做這個事情的,那我們爲什麼不直接使用Java動態代理,而要使用cglib呢?答案是cglib相比於JDK動態代理更加強大,JDK動態代理雖然簡單易用,但是其有一個致命缺陷是,只能對接口進行代理。如果要代理的類爲一個普通類、沒有接口,那麼Java動態代理就沒法使用了。

pom文件依賴

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

被代理對象

package cn.test.proxy.actor;

/**
 * 目標對象:演員
 */
public class ArtActor {

    /**
     * 基本表演
     */
    public void basicAct(Float money) {
        System.out.println("演員【"+getActorName()+"】收到錢:"+money+",開始基本表演。");
    }

    /**
     * 高難度表演
     */
    public void difficultyAct(Float money) {
        System.out.println("演員【"+getActorName()+"】收到錢:"+money+",開始高難度表演。");
    }

    /**
     * 演員名稱
     */
    public String getActorName(){
        return "小花";
    }
}

方法攔截器與代理類測試

package cn.test.proxy.play;

import cn.itheima.proxy.actor.ArtActor;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 用戶:劇組
 */
public class Play {

    public static void main(String[] args) {
      
        /**
         * 版本二:劇組通過經紀人人,找演員表演
         * 實現方式:
         *      第三方的cglib動態代理實現
         *  涉及到的類:
         *       EnHancer
         *  涉及到的方法:
         *      create()
         *  參數:
         *      Class:被代理類的字節碼
         *      Callback:如何代理。這裏是實現增強的地方。相當於InvocationHandler
         */
        // 創建目標對象(演員)
       final ArtActor actor = new ArtActor();

       // 創建代理對象(經紀人)
        ArtActor actorProxy = (ArtActor)Enhancer.create(
                actor.getClass(),

                new MethodInterceptor() {
                    /**
                     *實現增強功能方法:intercept()。相當於invoke()
                     * 參數:
                     *      proxy:代理對象引用。一般用不到
                     *      method:當前執行的方法對象
                     *      args:當前執行方法的參數列表
                     *      methodProxy:當前方法對象的代理引用。一般用不到
                     */
                    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

                        // 1.劇組找到經紀人
                        // 1.1.明確表演需求:方法名稱
                        String methodName = method.getName();

                        // 1.2.明確出場費用
                        Float money = (Float) args[0];

                        // 2.經紀人聯繫演員:是基本表演?還是高難度表演?給多少錢?
                        System.out.println("經紀人正在聯繫演員。");

                        // 2.1.是基本表演嗎?基本表演要求5000塊
                        Object retV = null;
                        if("basicAct".equals(methodName)){
                            if(money >= 5000){
                                System.out.println("基本表演,劇組錢給到位了。演員收下這個劇本。");
                                // 開始表演
                                retV = method.invoke(actor, money * 4 / 5);
                            }else{
                                System.out.println("劇組只給了:"+money+",錢不到位。演員表示檔期太滿。");
                            }
                        }

                        // 2.2.是高難度表演嗎?高難度表演要求10000塊
                        if("difficultyAct".equals(methodName)){
                            if(money >= 10000){
                                System.out.println("高難度表演,劇組錢給到位了。演員收下這個劇本。");
                                retV = method.invoke(actor,money*4/5);
                            }else{
                                System.out.println("劇組只給了:"+money+",錢不到位。演員直接表示拒絕這個劇本。");
                            }
                        }
                        return retV;
                    }
                }
        );

        // 經紀人代理演員,開始表演
        // 基本表演
        actorProxy.basicAct(5000f);

        System.out.println("----------------華麗麗分割線----------------");
        // 高難度表演
        actorProxy.difficultyAct(10000f);
    }
}

 

 

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