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

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

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

    stone2083

    CGlib簡(jiǎn)單介紹

    CGlib概述:
    cglib(Code Generation Library)是一個(gè)強(qiáng)大的,高性能,高質(zhì)量的Code生成類(lèi)庫(kù)。它可以在運(yùn)行期擴(kuò)展Java類(lèi)與實(shí)現(xiàn)Java接口。
    cglib封裝了asm,可以在運(yùn)行期動(dòng)態(tài)生成新的class。
    cglib用于AOP,jdk中的proxy必須基于接口,cglib卻沒(méi)有這個(gè)限制。

    CGlib應(yīng)用:
    以一個(gè)實(shí)例在簡(jiǎn)單介紹下cglib的應(yīng)用。
    我們模擬一個(gè)虛擬的場(chǎng)景,關(guān)于信息的管理。

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

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

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

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

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

    }
    至此,沒(méi)有涉及到cglib的內(nèi)容,因?yàn)樾枨筇?jiǎn)單了,但是接下來(lái),需求發(fā)生了改變,要求:

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

        
    private String name; // 會(huì)員登錄名

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

        
    /**
         * 權(quán)限校驗(yàn),如果會(huì)員名為:maurice,則有權(quán)限做操作,否則提示沒(méi)有權(quán)限
         
    */
        @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--代碼變動(dòng)如下:
    public class InfoManagerFactory {

        
    /**
         * 創(chuàng)建帶有權(quán)限檢驗(yàn)的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();
        }

        
    /**
         * 模擬:登錄會(huì)員沒(méi)有權(quán)限
         
    */
        
    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();
        }

        
    /**
         * 模擬:登錄會(huì)員有權(quán)限
         
    */
        
    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();
        }

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

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

    }
    執(zhí)行下代碼,發(fā)現(xiàn)這時(shí)client端中已經(jīng)加上了權(quán)限校驗(yàn)。
    同樣是InfoManager,為什么這時(shí)能多了權(quán)限的判斷呢?Factory中enhancer.create()返回的到底是什么對(duì)象呢?這個(gè)疑問(wèn)將在第三部分CGlib中解釋。
    這邊的代碼,其實(shí)是介紹了cglib中的enhancer功能.

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

    3)由于query功能用戶maurice才能使用,招來(lái)其他用戶的強(qiáng)烈的抱怨,所以權(quán)限再次變更,只有create,update,delete,才需要權(quán)限保護(hù),query任何人都可以使用。
    怎么辦?采用AuthProxy,使得InfoManager中的所有方法都被代理,加上了權(quán)限的判斷。當(dāng)然,最容易想到的辦法,就是在AuthProxy的intercept的方法中再做下判斷,如果代理的method是query,不需要權(quán)限驗(yàn)證。這么做,可以,但是一旦邏輯比較復(fù)雜的時(shí)候,intercept這個(gè)方法要做的事情會(huì)很多,邏輯會(huì)異常的復(fù)雜。
    幸好,cglib還提供了CallbackFilter。使用CallbackFilter,可以明確表明,被代理的類(lèi)(InfoManager)中不同的方法,被哪個(gè)攔截器(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
         * 如果調(diào)用query函數(shù),則使用第二個(gè)proxy
         * 否則,使用第一個(gè)proxy
         * </pre>
         
    */
        @Override
        
    public int accept(Method method) {
            
    if ("query".equals(method.getName())) {
                
    return AUTH_NOT_NEED;
            }
            
    return AUTH_NEED;
        }

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

        
    /**
         * 創(chuàng)建不同權(quán)限要求的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();
        }

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

    Client.java
    public class Client {

        
    public static void main(String[] args) {
            Client c 
    = new Client();
            c.selectivityAuthManager();
        }
        
        
    /**
         * 模擬:沒(méi)有權(quán)限的會(huì)員,可以作查詢操作
         
    */
        
    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();
        }

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

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

    }
    此時(shí),對(duì)于query的權(quán)限校驗(yàn)已經(jīng)被去掉了。


    通過(guò)一個(gè)模擬需求,簡(jiǎn)單介紹了cglib aop功能的使用。
    CGlib應(yīng)用非常廣,在spring,hibernate等框架中,被大量的使用。


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

    其實(shí)在剛才的例子中,cglib在代碼運(yùn)行期,動(dòng)態(tài)生成了InfoManager的子類(lèi),并且根據(jù)CallbackFilter的accept方法,覆寫(xiě)了InfoManager中的所有方法--去執(zhí)行相應(yīng)的MethodInterceptor的intercept方法。

    有興趣的朋友可以看看我反編譯的InfoManager的子類(lèi),就可以很明白知道具體的實(shí)現(xiàn)了。(需要有耐心才可以)
    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 閱讀(35631) 評(píng)論(22)  編輯  收藏 所屬分類(lèi): java

    Feedback

    # re: CGlib簡(jiǎn)單介紹 2008-07-03 16:51 zhen

    用cglib也產(chǎn)生了附加的問(wèn)題  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2008-07-03 22:07 stone2083

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

    我不清楚,你所謂使用cglib產(chǎn)生附加問(wèn)題,具體是什么問(wèn)題?  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2008-10-03 21:34 大鵬

    太強(qiáng)了,我頂!  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2009-05-05 16:16 SunnyWolf

    NB  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2009-09-16 11:04 tomcatlee

    牛掰的東東啊  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2009-10-09 16:40 名揚(yáng)/六耶子

    可以通過(guò)cglib動(dòng)態(tài)創(chuàng)建java對(duì)象么?就是傳入對(duì)象名,字段名,然后創(chuàng)建并返回所創(chuàng)建對(duì)象的實(shí)例?  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2009-10-10 10:38 stone2083

    @名揚(yáng)/六耶子
    cglib底層依賴了asm,它主要是在“動(dòng)態(tài)代理”場(chǎng)景下增加易用性。
    如果要?jiǎng)討B(tài)生成字段,方法,那么asm或者javassist這兩個(gè)技術(shù),更合適你。  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹[未登錄](méi) 2010-04-08 16:49 tylerLimin

    不錯(cuò)!  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹[未登錄](méi) 2010-09-28 22:46 pyzhu

    "有興趣的朋友可以看看我反編譯的InfoManager的子類(lèi),就可以很明白知道具體的實(shí)現(xiàn)了。"
    這個(gè)cglib在運(yùn)行期動(dòng)態(tài)生成的class你是如何獲取的,并用jad進(jìn)行反編碼的?
    一直沒(méi)找到這個(gè)動(dòng)態(tài)生成的class我也就無(wú)法對(duì)它進(jìn)行反編譯,莫非是直接放在jvm的堆內(nèi)存了吧?那該如何獲取它并反編譯它呢。。。
    期待答復(fù)~  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2010-09-29 09:18 stone2083

    @pyzhu
    用了比較猥瑣的辦法,
    debug,將動(dòng)態(tài)生成class的字節(jié)碼 輸入到文件中,然后反編譯得到的.  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹[未登錄](méi) 2010-09-29 23:11 pyzhu

    @stone2083
    一語(yǔ)驚醒夢(mèng)中人,呵呵。。。
    可是還有些不明白的地方,如何通過(guò)Class對(duì)象獲取對(duì)應(yīng)class字節(jié)碼呀?  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹[未登錄](méi) 2010-09-29 23:22 pyzhu

    @stone2083
    呵呵。。。想到一種方式,用javassist的ClassPool/CtClass應(yīng)該可以做到~  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹[未登錄](méi) 2010-10-06 01:36 pyzhu

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

    ps. javassist貌似不行  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2010-10-09 09:27 stone2083

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


      回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2010-11-03 13:31 stone2083

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

    詳見(jiàn):http://www.javaeye.com/topic/799827  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2011-11-09 15:21 yaohonv

    學(xué)習(xí)  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2013-10-24 16:14 擠饅頭

    樓主的代碼有無(wú)限遞歸啊。。。  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2013-10-24 16:18 擠饅頭

    @擠饅頭
    看錯(cuò)了,沒(méi)問(wèn)題  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2013-11-06 22:26 diegozhu

    @stone2083

    1. PG 不再穩(wěn)定.
    2. debug困難.  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2014-01-24 10:28 frogSF

    反編譯那段太難懂了~~~~
      回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹 2014-08-02 11:50 wanglj

    受教了,謝謝!將代碼download下來(lái)后,跑了跑,比之前的理解清晰多了。  回復(fù)  更多評(píng)論   

    # re: CGlib簡(jiǎn)單介紹[未登錄](méi) 2015-10-05 11:41 jones

    怎么反編譯子類(lèi)?  回復(fù)  更多評(píng)論   

    主站蜘蛛池模板: 国产中文字幕免费| 激情亚洲一区国产精品| 无遮挡呻吟娇喘视频免费播放| 国国内清清草原免费视频99| 久久久久亚洲av无码尤物| 亚洲第一视频在线观看免费| 亚洲国产精品人人做人人爱| 亚洲1区2区3区精华液| 在线精品免费视频| 久久国产亚洲精品| 免费观看成人毛片a片2008| 亚洲精品福利网站| 精品免费人成视频app| 久久久久亚洲精品无码蜜桃| 无码精品人妻一区二区三区免费看| 国产亚洲人成网站在线观看不卡| 一个人看的www在线免费视频| 亚洲福利在线播放| 又长又大又粗又硬3p免费视频| 亚洲国产成人久久综合碰| 一级做a爰黑人又硬又粗免费看51社区国产精品视| 免费看美女让人桶尿口| 亚洲日韩一区二区一无码| 天堂在线免费观看中文版| 国产91在线|亚洲| 最近免费中文字幕大全视频| 亚洲国产系列一区二区三区| 国产精品视频永久免费播放| 久久亚洲国产成人影院| 成人免费视频观看无遮挡| 亚洲日韩久久综合中文字幕| 在线jyzzjyzz免费视频| 亚洲av乱码一区二区三区按摩| 免费真实播放国产乱子伦| 污污免费在线观看| 亚洲一区二区三区无码影院| 91免费在线视频| 亚洲av色福利天堂| 100部毛片免费全部播放完整| 亚洲六月丁香六月婷婷蜜芽| 最近高清国语中文在线观看免费|