<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    stone2083

    CGlib簡單介紹

    CGlib概述:
    cglib(Code Generation Library)是一個強大的,高性能,高質量的Code生成類庫。它可以在運行期擴展Java類與實現Java接口。
    cglib封裝了asm,可以在運行期動態生成新的class。
    cglib用于AOP,jdk中的proxy必須基于接口,cglib卻沒有這個限制。

    CGlib應用:
    以一個實例在簡單介紹下cglib的應用。
    我們模擬一個虛擬的場景,關于信息的管理。

    1)原始需求是任何人可以操作信息的create,update,delete,query操作。
    InfoManager.java--封裝對信息的操作
    public class InfoManager {
        
    // 模擬查詢操作
        public void query() {
            System.out.println(
    "query");
        }
        
    // 模擬創建操作
        public void create() {
            System.out.println(
    "create");
        }
        
    // 模擬更新操作
        public void update() {
            System.out.println(
    "update");
        }
        
    // 模擬刪除操作
        public void delete() {
            System.out.println(
    "delete");
        }
    }
    InfoManagerFactory.java--工廠類
    public class InfoManagerFactory {
        
    private static InfoManager manger = new InfoManager();
        
    /**
         * 創建原始的InfoManager
         * 
         * 
    @return
         
    */
        
    public static InfoManager getInstance() {
            
    return manger;
        }
    }
    client.java--供客戶端調用
    public class Client {

        
    public static void main(String[] args) {
            Client c 
    = new Client();
            c.anyonecanManager();
        }

        
    /**
         * 模擬:沒有任何權限要求,任何人都可以操作
         
    */
        
    public void anyonecanManager() {
            System.out.println(
    "any one can do manager");
            InfoManager manager 
    = InfoManagerFactory.getInstance();
            doCRUD(manager);
            separatorLine();
        }

        
    /**
         * 對Info做增加/更新/刪除/查詢操作
         * 
         * 
    @param manager
         
    */
        
    private void doCRUD(InfoManager manager) {
            manager.create();
            manager.update();
            manager.delete();
            manager.query();
        }

        
    /**
         * 加一個分隔行,用于區分
         
    */
        
    private void separatorLine() {
            System.out.println(
    "################################");
        }

    }
    至此,沒有涉及到cglib的內容,因為需求太簡單了,但是接下來,需求發生了改變,要求:

    2)只有一個叫“maurice”的用戶登錄,才允許對信息進行create,update,delete,query的操作。
    怎么辦?難道在每個方法前,都加上一個權限判斷嗎?這樣重復邏輯太多了,于是乎想到了Proxy(代理模式),但是原先的InfoManager也沒有實現接口,不能采用jdk的proxy。那么cglib在這邊就要隆重登場。
    一旦使用cgblig,只需要添加一個MethodInterceptor的類以及修改factory代碼就可以實現這個需求。
    AuthProxy.java--權限校驗代理類
    public class AuthProxy implements MethodInterceptor {

        
    private String name; // 會員登錄名

        
    public AuthProxy(String name) {
            
    this.name = name;
        }

        
    /**
         * 權限校驗,如果會員名為:maurice,則有權限做操作,否則提示沒有權限
         
    */
        @Override
        
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            
    if (!"maurice".equals(this.name)) {
                System.out.println(
    "AuthProxy:you have no permits to do manager!");
                
    return null;
            }
            
    return proxy.invokeSuper(obj, args);
        }

        
    public String getName() {
            
    return name;
        }

        
    public void setName(String name) {
            
    this.name = name;
        }

    }
    InfoManagerFactory.java--代碼變動如下:
    public class InfoManagerFactory {

        
    /**
         * 創建帶有權限檢驗的InfoManager
         * 
         * 
    @param auth
         * 
    @return
         
    */
        
    public static InfoManager getAuthInstance(AuthProxy auth) {
            Enhancer enhancer 
    = new Enhancer();
            enhancer.setSuperclass(InfoManager.
    class);
            enhancer.setCallback(auth);
            
    return (InfoManager) enhancer.create();
        }

        
    }
    client.java--代碼修改如下
    public class Client {

        
    public static void main(String[] args) {
            Client c 
    = new Client();
            c.haveNoAuthManager();
            c.haveAuthManager();
        }

        
    /**
         * 模擬:登錄會員沒有權限
         
    */
        
    public void haveNoAuthManager() {
            System.out.println(
    "the loginer's name is not maurice,so have no permits do manager");
            InfoManager noAuthManager 
    = InfoManagerFactory.getAuthInstance(new AuthProxy("maurice1"));
            doCRUD(noAuthManager);
            separatorLine();
        }

        
    /**
         * 模擬:登錄會員有權限
         
    */
        
    public void haveAuthManager() {
            System.out.println(
    "the loginer's name is maurice,so have permits do manager");
            InfoManager authManager 
    = InfoManagerFactory.getAuthInstance(new AuthProxy("maurice"));
            doCRUD(authManager);
            separatorLine();
        }

        
    /**
         * 對Info做增加/更新/刪除/查詢操作
         * 
         * 
    @param manager
         
    */
        
    private void doCRUD(InfoManager manager) {
            manager.create();
            manager.update();
            manager.delete();
            manager.query();
        }

        
    /**
         * 加一個分隔行,用于區分
         
    */
        
    private void separatorLine() {
            System.out.println(
    "################################");
        }

    }
    執行下代碼,發現這時client端中已經加上了權限校驗。
    同樣是InfoManager,為什么這時能多了權限的判斷呢?Factory中enhancer.create()返回的到底是什么對象呢?這個疑問將在第三部分CGlib中解釋。
    這邊的代碼,其實是介紹了cglib中的enhancer功能.

    到這里,參照上面的代碼,就可以使用cglib帶來的aop功能了。但是為了更多介紹下cglib的功能,模擬需求再次發生變化:

    3)由于query功能用戶maurice才能使用,招來其他用戶的強烈的抱怨,所以權限再次變更,只有create,update,delete,才需要權限保護,query任何人都可以使用。
    怎么辦?采用AuthProxy,使得InfoManager中的所有方法都被代理,加上了權限的判斷。當然,最容易想到的辦法,就是在AuthProxy的intercept的方法中再做下判斷,如果代理的method是query,不需要權限驗證。這么做,可以,但是一旦邏輯比較復雜的時候,intercept這個方法要做的事情會很多,邏輯會異常的復雜。
    幸好,cglib還提供了CallbackFilter。使用CallbackFilter,可以明確表明,被代理的類(InfoManager)中不同的方法,被哪個攔截器(interceptor)攔截。
    AuthProxyFilter.java
    public class AuthProxyFilter implements CallbackFilter {

        
    private static final int AUTH_NEED     = 0;
        
    private static final int AUTH_NOT_NEED = 1;

        
    /**
         * <pre>
         * 選擇使用的proxy
         * 如果調用query函數,則使用第二個proxy
         * 否則,使用第一個proxy
         * </pre>
         
    */
        @Override
        
    public int accept(Method method) {
            
    if ("query".equals(method.getName())) {
                
    return AUTH_NOT_NEED;
            }
            
    return AUTH_NEED;
        }

    }
    這段代碼什么意思?其中的accept方法的意思是說,如果代理的方法是query(),那么使用第二個攔截器去攔截,如果代理的方法不是query(),那么使用第一個攔截器去攔截。所以我們只要再寫一個攔截器,不做權限校驗就行了。(其實,cglib中的NoOp.INSTANCE就是一個空的攔截器,只要配置上這個就可以了。)
    InfoManagerFactory.java--代碼修改如下:(配置不同的攔截器和filter)
    public class InfoManagerFactory {

        
    /**
         * 創建不同權限要求的InfoManager
         * 
         * 
    @param auth
         * 
    @return
         
    */
        
    public static InfoManager getSelectivityAuthInstance(AuthProxy auth) {
            Enhancer enhancer 
    = new Enhancer();
            enhancer.setSuperclass(InfoManager.
    class);
            enhancer.setCallbacks(
    new Callback[] { auth, NoOp.INSTANCE });
            enhancer.setCallbackFilter(
    new AuthProxyFilter());
            
    return (InfoManager) enhancer.create();
        }

    }
    記?。簊etCallbacks中的攔截器(interceptor)的順序,一定要和CallbackFilter里面指定的順序一致!!切忌。

    Client.java
    public class Client {

        
    public static void main(String[] args) {
            Client c 
    = new Client();
            c.selectivityAuthManager();
        }
        
        
    /**
         * 模擬:沒有權限的會員,可以作查詢操作
         
    */
        
    public void selectivityAuthManager() {
            System.out.println(
    "the loginer's name is not maurice,so have no permits do manager except do query operator");
            InfoManager authManager 
    = InfoManagerFactory.getSelectivityAuthInstance(new AuthProxy("maurice1"));
            doCRUD(authManager);
            separatorLine();
        }

        
    /**
         * 對Info做增加/更新/刪除/查詢操作
         * 
         * 
    @param manager
         
    */
        
    private void doCRUD(InfoManager manager) {
            manager.create();
            manager.update();
            manager.delete();
            manager.query();
        }

        
    /**
         * 加一個分隔行,用于區分
         
    */
        
    private void separatorLine() {
            System.out.println(
    "################################");
        }

    }
    此時,對于query的權限校驗已經被去掉了。


    通過一個模擬需求,簡單介紹了cglib aop功能的使用。
    CGlib應用非常廣,在spring,hibernate等框架中,被大量的使用。


    CGlib原理:
    cglib神奇嗎?其實一旦了解cglib enhancer的原理,一切就真相大白了。
    剛才在第二部分中,有個疑問:enhancer.create()到底返回了什么對象?

    其實在剛才的例子中,cglib在代碼運行期,動態生成了InfoManager的子類,并且根據CallbackFilter的accept方法,覆寫了InfoManager中的所有方法--去執行相應的MethodInterceptor的intercept方法。

    有興趣的朋友可以看看我反編譯的InfoManager的子類,就可以很明白知道具體的實現了。(需要有耐心才可以)
    InfoManager$$EnhancerByCGLIB$$de624598.jad
    // Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.geocities.com/kpdus/jad.html
    // Decompiler options: packimports(3) 
    // Source File Name:   <generated>

    package cn.eulic.codelab.cglib;

    import java.lang.reflect.Method;
    import net.sf.cglib.core.Signature;
    import net.sf.cglib.proxy.*;

    // Referenced classes of package cn.eulic.codelab.cglib:
    //            InfoManager

    public class CGLIB.BIND_CALLBACKS extends InfoManager
        
    implements Factory
    {

        
    static void CGLIB$STATICHOOK1()
        {
            Class class1;
            ClassLoader classloader;
            CGLIB$THREAD_CALLBACKS 
    = new ThreadLocal();
            classloader 
    = (class1 = Class.forName("cn.eulic.codelab.cglib.InfoManager$$EnhancerByCGLIB$$de624598")).getClassLoader();
            classloader;
            CGLIB$emptyArgs 
    = new Object[0];
            CGLIB$delete$
    0$Proxy = MethodProxy.create(classloader, (CGLIB$delete$0$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("delete"new Class[0])).getDeclaringClass(), class1, "()V""delete""CGLIB$delete$0");
            CGLIB$create$
    1$Proxy = MethodProxy.create(classloader, (CGLIB$create$1$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("create"new Class[0])).getDeclaringClass(), class1, "()V""create""CGLIB$create$1");
            CGLIB$query$
    2$Proxy = MethodProxy.create(classloader, (CGLIB$query$2$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("query"new Class[0])).getDeclaringClass(), class1, "()V""query""CGLIB$query$2");
            CGLIB$update$
    3$Proxy = MethodProxy.create(classloader, (CGLIB$update$3$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("update"new Class[0])).getDeclaringClass(), class1, "()V""update""CGLIB$update$3");
            CGLIB$finalize$
    4$Proxy = MethodProxy.create(classloader, (CGLIB$finalize$4$Method = Class.forName("java.lang.Object").getDeclaredMethod("finalize"new Class[0])).getDeclaringClass(), class1, "()V""finalize""CGLIB$finalize$4");
            CGLIB$hashCode$
    5$Proxy = MethodProxy.create(classloader, (CGLIB$hashCode$5$Method = Class.forName("java.lang.Object").getDeclaredMethod("hashCode"new Class[0])).getDeclaringClass(), class1, "()I""hashCode""CGLIB$hashCode$5");
            CGLIB$clone$
    6$Proxy = MethodProxy.create(classloader, (CGLIB$clone$6$Method = Class.forName("java.lang.Object").getDeclaredMethod("clone"new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/Object;""clone""CGLIB$clone$6");
            CGLIB$equals$
    7$Proxy = MethodProxy.create(classloader, (CGLIB$equals$7$Method = Class.forName("java.lang.Object").getDeclaredMethod("equals"new Class[] {
                Class.forName(
    "java.lang.Object")
            })).getDeclaringClass(), class1, 
    "(Ljava/lang/Object;)Z""equals""CGLIB$equals$7");
            CGLIB$toString$
    8$Proxy = MethodProxy.create(classloader, (CGLIB$toString$8$Method = Class.forName("java.lang.Object").getDeclaredMethod("toString"new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/String;""toString""CGLIB$toString$8");
            
    return;
        }

        
    final void CGLIB$delete$0()
        {
            
    super.delete();
        }

        
    public final void delete()
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    37;
               
    goto _L3 _L4
    _L3:
            
    break MISSING_BLOCK_LABEL_21;
    _L4:
            
    break MISSING_BLOCK_LABEL_37;
            
    this;
            CGLIB$delete$
    0$Method;
            CGLIB$emptyArgs;
            CGLIB$delete$
    0$Proxy;
            intercept();
            
    return;
            
    super.delete();
            
    return;
        }

        
    final void CGLIB$create$1()
        {
            
    super.create();
        }

        
    public final void create()
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    37;
               
    goto _L3 _L4
    _L3:
            
    break MISSING_BLOCK_LABEL_21;
    _L4:
            
    break MISSING_BLOCK_LABEL_37;
            
    this;
            CGLIB$create$
    1$Method;
            CGLIB$emptyArgs;
            CGLIB$create$
    1$Proxy;
            intercept();
            
    return;
            
    super.create();
            
    return;
        }

        
    final void CGLIB$query$2()
        {
            
    super.query();
        }

        
    public final void query()
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    37;
               
    goto _L3 _L4
    _L3:
            
    break MISSING_BLOCK_LABEL_21;
    _L4:
            
    break MISSING_BLOCK_LABEL_37;
            
    this;
            CGLIB$query$
    2$Method;
            CGLIB$emptyArgs;
            CGLIB$query$
    2$Proxy;
            intercept();
            
    return;
            
    super.query();
            
    return;
        }

        
    final void CGLIB$update$3()
        {
            
    super.update();
        }

        
    public final void update()
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    37;
               
    goto _L3 _L4
    _L3:
            
    break MISSING_BLOCK_LABEL_21;
    _L4:
            
    break MISSING_BLOCK_LABEL_37;
            
    this;
            CGLIB$update$
    3$Method;
            CGLIB$emptyArgs;
            CGLIB$update$
    3$Proxy;
            intercept();
            
    return;
            
    super.update();
            
    return;
        }

        
    final void CGLIB$finalize$4()
            
    throws Throwable
        {
            
    super.finalize();
        }

        
    protected final void finalize()
            
    throws Throwable
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    37;
               
    goto _L3 _L4
    _L3:
            
    break MISSING_BLOCK_LABEL_21;
    _L4:
            
    break MISSING_BLOCK_LABEL_37;
            
    this;
            CGLIB$finalize$
    4$Method;
            CGLIB$emptyArgs;
            CGLIB$finalize$
    4$Proxy;
            intercept();
            
    return;
            
    super.finalize();
            
    return;
        }

        
    final int CGLIB$hashCode$5()
        {
            
    return super.hashCode();
        }

        
    public final int hashCode()
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    52;
               
    goto _L3 _L4
    _L3:
            
    this;
            CGLIB$hashCode$
    5$Method;
            CGLIB$emptyArgs;
            CGLIB$hashCode$
    5$Proxy;
            intercept();
            JVM INSTR dup ;
            JVM INSTR ifnonnull 
    45;
               
    goto _L5 _L6
    _L5:
            JVM INSTR pop ;
            
    0;
              
    goto _L7
    _L6:
            (Number);
            intValue();
    _L7:
            
    return;
    _L4:
            
    return super.hashCode();
        }

        
    final Object CGLIB$clone$6()
            
    throws CloneNotSupportedException
        {
            
    return super.clone();
        }

        
    protected final Object clone()
            
    throws CloneNotSupportedException
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    37;
               
    goto _L3 _L4
    _L3:
            
    this;
            CGLIB$clone$
    6$Method;
            CGLIB$emptyArgs;
            CGLIB$clone$
    6$Proxy;
            intercept();
            
    return;
    _L4:
            
    return super.clone();
        }

        
    final boolean CGLIB$equals$7(Object obj)
        {
            
    return super.equals(obj);
        }

        
    public final boolean equals(Object obj)
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    57;
               
    goto _L3 _L4
    _L3:
            
    this;
            CGLIB$equals$
    7$Method;
            
    new Object[] {
                obj
            };
            CGLIB$equals$
    7$Proxy;
            intercept();
            JVM INSTR dup ;
            JVM INSTR ifnonnull 
    50;
               
    goto _L5 _L6
    _L5:
            JVM INSTR pop ;
            
    false;
              
    goto _L7
    _L6:
            (Boolean);
            booleanValue();
    _L7:
            
    return;
    _L4:
            
    return super.equals(obj);
        }

        
    final String CGLIB$toString$8()
        {
            
    return super.toString();
        }

        
    public final String toString()
        {
            CGLIB$CALLBACK_0;
            
    if(CGLIB$CALLBACK_0 != nullgoto _L2; else goto _L1
    _L1:
            JVM INSTR pop ;
            CGLIB$BIND_CALLBACKS(
    this);
            CGLIB$CALLBACK_0;
    _L2:
            JVM INSTR dup ;
            JVM INSTR ifnull 
    40;
               
    goto _L3 _L4
    _L3:
            
    this;
            CGLIB$toString$
    8$Method;
            CGLIB$emptyArgs;
            CGLIB$toString$
    8$Proxy;
            intercept();
            (String);
            
    return;
    _L4:
            
    return super.toString();
        }

        
    public static MethodProxy CGLIB$findMethodProxy(Signature signature)
        {
            String s 
    = signature.toString();
            s;
            s.hashCode();
            JVM INSTR lookupswitch 
    9default 200
        
    //                   -1949253108: 92
        
    //                   -1574182249: 104
        
    //                   -1166709331: 116
        
    //                   -508378822: 128
        
    //                   -358764054: 140
        
    //                   598313209: 152
        
    //                   1826985398: 164
        
    //                   1913648695: 176
        
    //                   1984935277: 188;
               goto _L1 _L2 _L3 _L4 _L5 _L6 _L7 _L8 _L9 _L10
    _L2:
            
    "update()V";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L11 _L12
    _L12:
            
    break MISSING_BLOCK_LABEL_201;
    _L11:
            
    return CGLIB$update$3$Proxy;
    _L3:
            
    "finalize()V";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L13 _L14
    _L14:
            
    break MISSING_BLOCK_LABEL_201;
    _L13:
            
    return CGLIB$finalize$4$Proxy;
    _L4:
            
    "query()V";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L15 _L16
    _L16:
            
    break MISSING_BLOCK_LABEL_201;
    _L15:
            
    return CGLIB$query$2$Proxy;
    _L5:
            
    "clone()Ljava/lang/Object;";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L17 _L18
    _L18:
            
    break MISSING_BLOCK_LABEL_201;
    _L17:
            
    return CGLIB$clone$6$Proxy;
    _L6:
            
    "delete()V";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L19 _L20
    _L20:
            
    break MISSING_BLOCK_LABEL_201;
    _L19:
            
    return CGLIB$delete$0$Proxy;
    _L7:
            
    "create()V";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L21 _L22
    _L22:
            
    break MISSING_BLOCK_LABEL_201;
    _L21:
            
    return CGLIB$create$1$Proxy;
    _L8:
            
    "equals(Ljava/lang/Object;)Z";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L23 _L24
    _L24:
            
    break MISSING_BLOCK_LABEL_201;
    _L23:
            
    return CGLIB$equals$7$Proxy;
    _L9:
            
    "toString()Ljava/lang/String;";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L25 _L26
    _L26:
            
    break MISSING_BLOCK_LABEL_201;
    _L25:
            
    return CGLIB$toString$8$Proxy;
    _L10:
            
    "hashCode()I";
            equals();
            JVM INSTR ifeq 
    201;
               
    goto _L27 _L28
    _L28:
            
    break MISSING_BLOCK_LABEL_201;
    _L27:
            
    return CGLIB$hashCode$5$Proxy;
    _L1:
            JVM INSTR pop ;
            
    return null;
        }

        
    public static void CGLIB$SET_THREAD_CALLBACKS(Callback acallback[])
        {
            CGLIB$THREAD_CALLBACKS.set(acallback);
        }

        
    public static void CGLIB$SET_STATIC_CALLBACKS(Callback acallback[])
        {
            CGLIB$STATIC_CALLBACKS 
    = acallback;
        }

        
    private static final void CGLIB$BIND_CALLBACKS(Object obj)
        {
            CGLIB.STATIC_CALLBACKS static_callbacks 
    = (CGLIB.STATIC_CALLBACKS)obj;
            
    if(static_callbacks.CGLIB$BOUND) goto _L2; else goto _L1
    _L1:
            Object obj1;
            static_callbacks.CGLIB$BOUND 
    = true;
            obj1 
    = CGLIB$THREAD_CALLBACKS.get();
            obj1;
            
    if(obj1 != nullgoto _L4; else goto _L3
    _L3:
            JVM INSTR pop ;
            CGLIB$STATIC_CALLBACKS;
            
    if(CGLIB$STATIC_CALLBACKS != nullgoto _L4; else goto _L5
    _L5:
            JVM INSTR pop ;
              
    goto _L2
    _L4:
            (Callback[]);
            static_callbacks;
            JVM INSTR swap ;
            
    0;
            JVM INSTR aaload ;
            (MethodInterceptor);
            CGLIB$CALLBACK_0;
    _L2:
        }

        
    public Object newInstance(Callback acallback[])
        {
            CGLIB$SET_THREAD_CALLBACKS(acallback);
            CGLIB$SET_THREAD_CALLBACKS(
    null);
            
    return new <init>();
        }

        
    public Object newInstance(Callback callback)
        {
            CGLIB$SET_THREAD_CALLBACKS(
    new Callback[] {
                callback
            });
            CGLIB$SET_THREAD_CALLBACKS(
    null);
            
    return new <init>();
        }

        
    public Object newInstance(Class aclass[], Object aobj[], Callback acallback[])
        {
            CGLIB$SET_THREAD_CALLBACKS(acallback);
            JVM INSTR 
    new #2   <Class InfoManager$$EnhancerByCGLIB$$de624598>;
            JVM INSTR dup ;
            aclass;
            aclass.length;
            JVM INSTR tableswitch 
    0 0default 35
        
    //                   0 28;
               goto _L1 _L2
    _L2:
            JVM INSTR pop ;
            
    <init>();
              
    goto _L3
    _L1:
            JVM INSTR pop ;
            
    throw new IllegalArgumentException("Constructor not found");
    _L3:
            CGLIB$SET_THREAD_CALLBACKS(
    null);
            
    return;
        }

        
    public Callback getCallback(int i)
        {
            CGLIB$BIND_CALLBACKS(
    this);
            
    this;
            i;
            JVM INSTR tableswitch 
    0 0default 30
        
    //                   0 24;
               goto _L1 _L2
    _L2:
            CGLIB$CALLBACK_0;
              
    goto _L3
    _L1:
            JVM INSTR pop ;
            
    null;
    _L3:
            
    return;
        }

        
    public void setCallback(int i, Callback callback)
        {
            
    this;
            callback;
            i;
            JVM INSTR tableswitch 
    0 0default 29
        
    //                   0 20;
               goto _L1 _L2
    _L2:
            (MethodInterceptor);
            CGLIB$CALLBACK_0;
              
    goto _L3
    _L1:
            JVM INSTR pop2 ;
    _L3:
        }

        
    public Callback[] getCallbacks()
        {
            CGLIB$BIND_CALLBACKS(
    this);
            
    this;
            
    return (new Callback[] {
                CGLIB$CALLBACK_0
            });
        }

        
    public void setCallbacks(Callback acallback[])
        {
            
    this;
            acallback;
            JVM INSTR dup2 ;
            
    0;
            JVM INSTR aaload ;
            (MethodInterceptor);
            CGLIB$CALLBACK_0;
        }

        
    private boolean CGLIB$BOUND;
        
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
        
    private static final Callback CGLIB$STATIC_CALLBACKS[];
        
    private MethodInterceptor CGLIB$CALLBACK_0;
        
    private static final Method CGLIB$delete$0$Method;
        
    private static final MethodProxy CGLIB$delete$0$Proxy;
        
    private static final Object CGLIB$emptyArgs[];
        
    private static final Method CGLIB$create$1$Method;
        
    private static final MethodProxy CGLIB$create$1$Proxy;
        
    private static final Method CGLIB$query$2$Method;
        
    private static final MethodProxy CGLIB$query$2$Proxy;
        
    private static final Method CGLIB$update$3$Method;
        
    private static final MethodProxy CGLIB$update$3$Proxy;
        
    private static final Method CGLIB$finalize$4$Method;
        
    private static final MethodProxy CGLIB$finalize$4$Proxy;
        
    private static final Method CGLIB$hashCode$5$Method;
        
    private static final MethodProxy CGLIB$hashCode$5$Proxy;
        
    private static final Method CGLIB$clone$6$Method;
        
    private static final MethodProxy CGLIB$clone$6$Proxy;
        
    private static final Method CGLIB$equals$7$Method;
        
    private static final MethodProxy CGLIB$equals$7$Proxy;
        
    private static final Method CGLIB$toString$8$Method;
        
    private static final MethodProxy CGLIB$toString$8$Proxy;

        
    static 
        {
            CGLIB$STATICHOOK1();
        }

        
    public ()
        {
            CGLIB$BIND_CALLBACKS(
    this);
        }
    }


    附件如下:
    cglib sample

    posted on 2008-03-16 22:50 stone2083 閱讀(35629) 評論(22)  編輯  收藏 所屬分類: java

    Feedback

    # re: CGlib簡單介紹 2008-07-03 16:51 zhen

    用cglib也產生了附加的問題  回復  更多評論   

    # re: CGlib簡單介紹 2008-07-03 22:07 stone2083

    不可否認,每項技術總會存在弊端,比如cglib,導致jvm Permanet Generation 不再穩定,如果配置不當,并且大量生成cglib代理類的時候,出現out of memory;
    又或者,調試代理類的時候,相當不方便...
    但是cglib有他可喜的一面,底層采用asm,動態生成字節碼,比jdk proxy效率高了不知多少;為spring aop提供了底層的一種實現;hibernate使用cglib動態生成DO/PO (接口層對象)字節碼...應用是何等的廣泛.
    為java靜態語言提供了動態特性(當然,底層是asm功勞),多么可喜.

    我不清楚,你所謂使用cglib產生附加問題,具體是什么問題?  回復  更多評論   

    # re: CGlib簡單介紹 2008-10-03 21:34 大鵬

    太強了,我頂!  回復  更多評論   

    # re: CGlib簡單介紹 2009-05-05 16:16 SunnyWolf

    NB  回復  更多評論   

    # re: CGlib簡單介紹 2009-09-16 11:04 tomcatlee

    牛掰的東東啊  回復  更多評論   

    # re: CGlib簡單介紹 2009-10-09 16:40 名揚/六耶子

    可以通過cglib動態創建java對象么?就是傳入對象名,字段名,然后創建并返回所創建對象的實例?  回復  更多評論   

    # re: CGlib簡單介紹 2009-10-10 10:38 stone2083

    @名揚/六耶子
    cglib底層依賴了asm,它主要是在“動態代理”場景下增加易用性。
    如果要動態生成字段,方法,那么asm或者javassist這兩個技術,更合適你。  回復  更多評論   

    # re: CGlib簡單介紹[未登錄] 2010-04-08 16:49 tylerLimin

    不錯!  回復  更多評論   

    # re: CGlib簡單介紹[未登錄] 2010-09-28 22:46 pyzhu

    "有興趣的朋友可以看看我反編譯的InfoManager的子類,就可以很明白知道具體的實現了。"
    這個cglib在運行期動態生成的class你是如何獲取的,并用jad進行反編碼的?
    一直沒找到這個動態生成的class我也就無法對它進行反編譯,莫非是直接放在jvm的堆內存了吧?那該如何獲取它并反編譯它呢。。。
    期待答復~  回復  更多評論   

    # re: CGlib簡單介紹 2010-09-29 09:18 stone2083

    @pyzhu
    用了比較猥瑣的辦法,
    debug,將動態生成class的字節碼 輸入到文件中,然后反編譯得到的.  回復  更多評論   

    # re: CGlib簡單介紹[未登錄] 2010-09-29 23:11 pyzhu

    @stone2083
    一語驚醒夢中人,呵呵。。。
    可是還有些不明白的地方,如何通過Class對象獲取對應class字節碼呀?  回復  更多評論   

    # re: CGlib簡單介紹[未登錄] 2010-09-29 23:22 pyzhu

    @stone2083
    呵呵。。。想到一種方式,用javassist的ClassPool/CtClass應該可以做到~  回復  更多評論   

    # re: CGlib簡單介紹[未登錄] 2010-10-06 01:36 pyzhu

    我發現我真是傻呀,竟然一直去尋找這樣一種方式:“如何通過Class實例對象得到class字節碼,然后將字節碼寫入文件再反編譯,如此來獲取源碼”。。。
    哈哈。。。真是笨得要命哦~
    反倒忘記了cglib的source code了,嘻嘻。。。直接修改net.sf.cglib.core.AbstractClassGenerator.create(Object key)方法,將cglib取到的字節碼寫入文檔再反編譯不就ok了么~

    ps. javassist貌似不行  回復  更多評論   

    # re: CGlib簡單介紹 2010-10-09 09:27 stone2083

    @pyzhu
    修改源碼也是一種方法 :)
    我是在debug的時候,Variables窗體中,編寫java代碼,拿到class變量信息做自己的處理


      回復  更多評論   

    # re: CGlib簡單介紹 2010-11-03 13:31 stone2083

    @pyzhu
    得到同事指點,還有一種更好的方法:
    system.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "指定輸出目錄"); 

    詳見:http://www.javaeye.com/topic/799827  回復  更多評論   

    # re: CGlib簡單介紹 2011-11-09 15:21 yaohonv

    學習  回復  更多評論   

    # re: CGlib簡單介紹 2013-10-24 16:14 擠饅頭

    樓主的代碼有無限遞歸啊。。。  回復  更多評論   

    # re: CGlib簡單介紹 2013-10-24 16:18 擠饅頭

    @擠饅頭
    看錯了,沒問題  回復  更多評論   

    # re: CGlib簡單介紹 2013-11-06 22:26 diegozhu

    @stone2083

    1. PG 不再穩定.
    2. debug困難.  回復  更多評論   

    # re: CGlib簡單介紹 2014-01-24 10:28 frogSF

    反編譯那段太難懂了~~~~
      回復  更多評論   

    # re: CGlib簡單介紹 2014-08-02 11:50 wanglj

    受教了,謝謝!將代碼download下來后,跑了跑,比之前的理解清晰多了。  回復  更多評論   

    # re: CGlib簡單介紹[未登錄] 2015-10-05 11:41 jones

    怎么反編譯子類?  回復  更多評論   

    主站蜘蛛池模板: 高潮毛片无遮挡高清免费| 免费在线中文日本| 国产在线19禁免费观看| 羞羞视频免费网站入口| 亚洲av无码不卡| 亚洲国产成人久久综合一 | 久久精品国产亚洲AV| 亚洲中文字幕在线第六区| 久久午夜夜伦鲁鲁片免费无码影视| 亚洲中文无码永久免费| 免费精品视频在线| 久久91亚洲精品中文字幕| 免费看片免费播放| 人人玩人人添人人澡免费| 久久精品国产亚洲av瑜伽| 亚洲成Av人片乱码色午夜| 国产高清在线精品免费软件| 黄视频在线观看免费| 亚洲欧洲国产综合AV无码久久| 好看的电影网站亚洲一区| 日日操夜夜操免费视频| 免费国产污网站在线观看15| 免费人成再在线观看网站| 亚洲性69影院在线观看| 亚洲一区AV无码少妇电影☆| 日韩精品免费电影| free哆啪啪免费永久| 久久久久国色AV免费观看| 国产精品亚洲综合网站| 亚洲AV一二三区成人影片| 久久久久久久综合日本亚洲 | 亚洲精品国产自在久久| 亚洲第一成年免费网站| 久久久久久国产精品免费免费男同| 日日摸日日碰夜夜爽亚洲| 亚洲综合久久一本伊伊区| 亚洲无线电影官网| 亚洲一区无码中文字幕| 亚洲女人被黑人巨大进入| 日日操夜夜操免费视频| 啦啦啦手机完整免费高清观看|