CGlib简单介绍

CGLIB(Code Generation Library)详解 什么是CGLIB CGLIB是一个强大的、高性能的代码生成库。其被广泛应用于AOP框架(Spring、dynaop)中,用以提供方法拦截操作。Hibernate作为一个比较受欢迎的ORM框架,同样使用CGLIB来代理单端(多对一和一对一)关联(延迟提取集合使用的另一种机制)。CGLIB作为一个开源项目,其代码托管在github,地址为:https://github.com/cglib/cglib为什么 阅读详情

原文地址:http://www.blogjava.net/stone2083/archive/2008/03/16/186615.html

如果原文禁止转载,请联系博主,我会马上删除


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();
    }

}
记住:setCallbacks中的拦截器(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 != null) goto _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 != null) goto _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 != null) goto _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 != null) goto _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 != null) goto _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 != null) goto _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 != null) goto _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 != null) goto _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 != null) goto _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 9: default 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 != null) goto _L4; else goto _L3
_L3:
        JVM INSTR pop ;
        CGLIB$STATIC_CALLBACKS;
        if(CGLIB$STATIC_CALLBACKS != null) goto _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 0: default 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 0: default 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 0: default 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);
    }
}



深入理解动态代理:JDK动态代理与CGLIB动态代理 动态代理是一种在运行时创建代理对象的技术,通过代理对象来控制对原对象的访问,能够在不修改原对象的情况下添加额外的功能。JDK动态代理:基于Java反射机制,只能代理实现了接口的类。CGLIB动态代理:基于字节码生成技术,可以代理没有实现接口的类。// 抽象主题接口动态代理在Java中提供了一种灵活而强大的机制,能够在运行时为目标对象添加额外的功能。JDK动态代理和CGLIB动态代理各有优势和适用场景,开发者可以根据具体需求选择合适的代理机制。希望这篇文章对你理解动态代理有所帮助。 阅读详情

相关推荐

学习笔记之——Event Camera(事件相机)调研

概述 Event Camera是一种bio-inspired sensor,对应的领域为bio-inspired vision。对于传统的相机,从某种程度上,是捕获一个静态/静止的空间,而Event Camera的目的是:敏感地捕捉运动的物体。 对于传统RGB-camera,相机传回的信息是同步的,所谓同步,就是在某一时刻t,相机会进行曝光,把这一时刻所有的像素填在一个矩阵里回传,一张照片就诞生了。一张照片上所有的像素都对应着同一时刻。至于视频,不过是很多帧的图片,相邻图片间的时间间隔...

gwpscut的博客 3万+

【深度思考】聊聊CGLIB动态代理原理

聊聊CGLIB动态代理原理。

申城异乡人 2789

Ubuntu+Dify实战:如何让大模型知识库完美支持图片召回(附避坑指南)

本文详细介绍了在Ubuntu系统上部署Dify平台,并实现大模型知识库图片召回功能的完整实战方案。通过解析Dify处理图片的底层逻辑,重点讲解了配置Nginx代理服务器将本地图片路径转换为可公开访问URL的核心工程步骤,并提供了文档预处理、环境变量配置以及父子分段策略等高级技巧,帮助开发者构建图文并茂的AI应用,有效提升知识库的丰富性和用户体验。

c7d8e的博客 445

动态代理之 cglib 实现

(尊重劳动成果,转载请注明出处:https://blog.youkuaiyun.com/qq_25827845/article/details/87513102冷血之心的博客) 目录 前言: 正文: AOP(面向切面编程) JDK动态代理 cglib实现动态代理 cglib包结构: cglib动态代理相关的基础类: cglib动态代理Demo 总结: 前言:         这篇文...

冷血之心的博客 9286

获取上传至DMS服务器上文件的URL

如果需要失效时间延长会设置URL永久有效, 可以去修改函数SCMS_URL_GENERATE的参数DURATION 或EXPIRATION ,DURATION最大时间是999999,若需要永久有效,则需要设置EXPIRATION的时间,这时系统会忽略DURATION的参数,生成URL的时候 SCMS_URL_GENERATE会调用SCMS_URL_SIGN函数这是其中默认这是了URL的生效时间为两小时。

一只学习的渣渣 540

ROS Navigation global_planner框架解析

ROS Navigation global_planner框架解析主要讲一下我看源码总结的框架,如果大家跟着这个框架看源码的话可能会看的比较快。主要讲解global_planner关键配置参数含义及关键函数Astar,Dijkstra,QuadraticCalculator::calculatePotential,PotentialCalculator::calculatePotential,GridPath::getPath,GradientPath::getPath.

Jeff_Lee_的博客 4693

Sping中的两个概念:IoC 和 AOP

CGlib概述:cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。cglib封装了asm,可以在运行期动态生成新的class。cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。CGlib应用:以一个实例在简单介绍下cglib的应用。我们模拟一个虚拟的场景,关于信

1021

用nTopology五分钟生成三维Voronoi泡沫:节点式建模从原理到实操

多孔结构在增材制造与轻量化设计中应用广泛,其中Voronoi泡沫因其优异的缓冲吸能和比刚度表现备受关注。传统CAD建模需处理复杂布尔运算和网格修复,而隐式建模通过数学场描述几何体,将空间距离与密度分布转化为可视化节点,大幅降低操作门槛。nTopology基于场驱动与参数化逻辑,无需编写命令,即可实时调节胞元尺寸、壁厚及随机种子,快速生成可打印的泡沫实体。这种工作流适用于缓冲垫、医疗植入体、航空支架等场景,也为梯度密度结构与力学仿真验证提供了高效路径。本文围绕三维Voronoi泡沫的生成原理与节点操作流程,详

weixin_26767391的博客 147

CGLib介绍

1. CGLIB介绍 CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库, 它可以在运行期扩展Java类与实现Java接口。CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring AOP为他们提供方法的interception(拦截)。CGLIB包的底层是通过使用一个小而快的字节码处理框...

古月的博客 2612

大模型系列——Ollama简明教程

在这篇文章中,我们将了解如何使用 Ollama、如何在 Ollama 中创建自己的模型 以及如何使用 Ollama 构建聊天机器人。这是深入研究 Ollama 的第一部分,以及我所学到的有关本地 LLM 的知识以及如何将它们用于基于推理的应用程序。在这篇文章中,你将了解——

2401_84052244的博客 1万+

LVGL colorwheel组件教程一(调色板)

【代码】LVGL colorwheel组件教程一(调色板)

摸鱼专家 427

CGLIB介绍与原理

CGLIB介绍与原理(部分节选自网络) 一、什么是CGLIB? CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。 二、CGLIB原理 CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final

zghwaicsdn的专栏 6万+

Altium Designer20 PCB板子绘制

版层 top layer 顶层 bottom layer 底层 设置板子大小 布局 过孔 top layer层连到bottom layer层。通过via连接。 设置线宽 在design rules里可以设置线宽。 右键new rule 可以新增线宽,电源设置成20mil 还可以设置很多其他的线宽 修改安全距离 安全距离太短容易出现毛刺,然后短路,一般设置成20mil 修改元器件旋转角度 修改rotation step,每次旋转45°。 修改光标大小 下面的cursor type是修改光标

及时总结 2581

CGLIB介绍

CGLIB(Code Generation Library)是一个高性能、强大的开源代码生成库,主要用于在运行时动态生成类或增强现有类的功能。它是 Java 动态代理机制的一种实现方式,广泛应用于像 Spring 和 Hibernate 这样的框架中,尤其是在 AOP(面向切面编程)和懒加载等场景下。CGLIB 的核心思想是通过生成目标类的子类(动态代理类),并在子类中拦截父类方法的调用,以实现增强功能。CGLIB 动态生成的子类继承了目标类,并重写了目标类中的方法。接口来拦截目标方法的调用。

qq_35842623的博客 993

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

cglib 介绍 原理 使用 demo examples

 翻译 原文:http://www.ociweb.com/jnb/jnbNov2005.html1.CGLIB包的介绍    代理为控制要访问的目标对象提供了一种途径。当访问对象时,它引入了一个间接的层。JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,当它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接

cb_121的专栏 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

java cglib_CGlib简单介绍

//DecompiledbyJadv1.5.8e.Copyright2001PavelKouznetsov.//Jadhomepage:http://www.geocities.com/kpdus/jad.html//Decompileroptions:packimports(3)//SourceFileName:packagecn.eulic.codelab.cg...

weixin_42517406的博客 745

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

CGLib 介绍与原理

CGLIB介绍与原理一、什么是CGLIB?CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。二、CGLIB原理CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦

Heqianqian的博客 1003

mica cglib 增强——【01】cglib bean copy 介绍

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34195546的博客 203

CGLIB 简单介绍

CGlib概述: cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。 cglib封装了asm,可以在运行期动态生成新的class。 cglib用于AOP,jdk中的pr

dennyWang的专栏 1027
上一篇: jqGrid与Struts2的结合应用(十) —— 真正的自定义表单查询
下一篇: jQuery 精简版弹出对话框层
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值