Error[8]: Undefined offset: 7, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

cglib动态代理使用和源码分析心得 前言

前几天使用公司项目,分析到某个代码接口实现类扫包增强型执行,就是使用的cglib动态代理模式,用来实现对日志打印、分布式锁、事务和异步线程池执行的增强。这里的底层原理是怎样,我下文进行表述。

使用

maven依赖引入
创建一个maven项目,pom.xml文件引入如下的依赖。

	
        
            cglib
            cglib
            3.2.12
        
    

拦截类说明和创建
创建一个拦截器类CglibMethodInterceptor,实现接口net.sf.cglib.proxy.MethodInterceptor,对应的方法如下:

public class CglibMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("<<<<<日志收集开始...>>>>>>>");
        Object reuslt = proxy.invokeSuper(obj, args);
        System.out.println("<<<<<日志收集结束...>>>>>>>");
        return reuslt;
    }
}

proxy为代理类,obj为代理对象,args为目标参数。proxy.invokeSuper(obj,args)为执行代理对象的目标方法。method为目标方法。

如果需要使用代理,则编写如下的方法:

public class TestProxy {
    public static void main(String[] args) {
        //System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E:\code");
        CglibMethodInterceptor cglibMethodInterceptor = new CglibMethodInterceptor();
        Enhancer enhancer = new Enhancer();
// 设置代理类的父类
        enhancer.setSuperclass(HelloServiceImpl.class);
// 设置回调对象
        enhancer.setCallback(cglibMethodInterceptor);
// 创建代理对象
        HelloService orderService = (HelloServiceImpl) enhancer.create();
        orderService.hello();
    }
}

Enhancer这里要加入回调拦截器,就是通过setCallback方法进行的,被代理类在setSuperclass来传入的。代理对象通过enhancer#create()方法来创建的。这里可以看到cglib动态代理是通过继承法来进行代理的。那这里底层原理是怎样的,下一节可以展示的。

cglib动态代理原理


如图所示,cglib动态代理生成三个类,第一个的父类才是被代理的类,另外两个是cglib包的enhancer和fastClass的子类。当调用被代理类的方法hello时,走如下的代码:

public final void hello() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$hello
 public Object invokeSuper(Object obj, Object[] args) throws Throwable {
        try {
            init();
            FastClassInfo fci = fastClassInfo;
            return fci.f2.invoke(fci.i2, obj, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }
$Method, CGLIB$emptyArgs, CGLIB$hello
 private static class FastClassInfo
    {
        FastClass f1;
        FastClass f2;
        int i1;
        int i2;
    }
$Proxy); } else { super.hello(); } }

这里MethodInterceptor 是上面的实现子类,它为null则直接执行被代理类对应的方法,如果不为空则执行对应的intercept方法。而fastClass如何调用对应的代理类呢?那请看下面的代码:

public int getIndex(Class[] var1) {
        switch(var1.length) {
        case 0:
            return 0;
        default:
            return -1;
        }
    }

    public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
        HelloServiceImpl var10000 = (HelloServiceImpl)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                var10000.hello();
                return null;
            case 1:
                return new Boolean(var10000.equals(var3[0]));
            case 2:
                return var10000.toString();
            case 3:
                return new Integer(var10000.hashCode());
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }
[+++]

Fastclass类的作用是创建索引机制。他的子类就是上面的第二个,对应生成代码如下:

[+++]

如果index为0,则执行被代理类的hello。从这里可以看出对应的实现不是通过反射而是通过继承。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 8, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

cglib动态代理使用和源码分析心得 前言

前几天使用公司项目,分析到某个代码接口实现类扫包增强型执行,就是使用的cglib动态代理模式,用来实现对日志打印、分布式锁、事务和异步线程池执行的增强。这里的底层原理是怎样,我下文进行表述。

使用

maven依赖引入
创建一个maven项目,pom.xml文件引入如下的依赖。

	
        
            cglib
            cglib
            3.2.12
        
    

拦截类说明和创建
创建一个拦截器类CglibMethodInterceptor,实现接口net.sf.cglib.proxy.MethodInterceptor,对应的方法如下:

public class CglibMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("<<<<<日志收集开始...>>>>>>>");
        Object reuslt = proxy.invokeSuper(obj, args);
        System.out.println("<<<<<日志收集结束...>>>>>>>");
        return reuslt;
    }
}

proxy为代理类,obj为代理对象,args为目标参数。proxy.invokeSuper(obj,args)为执行代理对象的目标方法。method为目标方法。

如果需要使用代理,则编写如下的方法:

public class TestProxy {
    public static void main(String[] args) {
        //System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E:\code");
        CglibMethodInterceptor cglibMethodInterceptor = new CglibMethodInterceptor();
        Enhancer enhancer = new Enhancer();
// 设置代理类的父类
        enhancer.setSuperclass(HelloServiceImpl.class);
// 设置回调对象
        enhancer.setCallback(cglibMethodInterceptor);
// 创建代理对象
        HelloService orderService = (HelloServiceImpl) enhancer.create();
        orderService.hello();
    }
}

Enhancer这里要加入回调拦截器,就是通过setCallback方法进行的,被代理类在setSuperclass来传入的。代理对象通过enhancer#create()方法来创建的。这里可以看到cglib动态代理是通过继承法来进行代理的。那这里底层原理是怎样的,下一节可以展示的。

cglib动态代理原理


如图所示,cglib动态代理生成三个类,第一个的父类才是被代理的类,另外两个是cglib包的enhancer和fastClass的子类。当调用被代理类的方法hello时,走如下的代码:

public final void hello() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$hello
 public Object invokeSuper(Object obj, Object[] args) throws Throwable {
        try {
            init();
            FastClassInfo fci = fastClassInfo;
            return fci.f2.invoke(fci.i2, obj, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }
$Method, CGLIB$emptyArgs, CGLIB$hello
 private static class FastClassInfo
    {
        FastClass f1;
        FastClass f2;
        int i1;
        int i2;
    }
$Proxy); } else { super.hello(); } }

这里MethodInterceptor 是上面的实现子类,它为null则直接执行被代理类对应的方法,如果不为空则执行对应的intercept方法。而fastClass如何调用对应的代理类呢?那请看下面的代码:

public int getIndex(Class[] var1) {
        switch(var1.length) {
        case 0:
            return 0;
        default:
            return -1;
        }
    }

    public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
        HelloServiceImpl var10000 = (HelloServiceImpl)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                var10000.hello();
                return null;
            case 1:
                return new Boolean(var10000.equals(var3[0]));
            case 2:
                return var10000.toString();
            case 3:
                return new Integer(var10000.hashCode());
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

Fastclass类的作用是创建索引机制。他的子类就是上面的第二个,对应生成代码如下:

[+++]

如果index为0,则执行被代理类的hello。从这里可以看出对应的实现不是通过反射而是通过继承。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
cglib动态代理使用和源码分析心得_随笔_内存溢出

cglib动态代理使用和源码分析心得

cglib动态代理使用和源码分析心得,第1张

cglib动态代理使用和源码分析心得 前言

前几天使用公司项目,分析到某个代码接口实现类扫包增强型执行,就是使用的cglib动态代理模式,用来实现对日志打印、分布式锁、事务和异步线程池执行的增强。这里的底层原理是怎样,我下文进行表述。

使用

maven依赖引入
创建一个maven项目,pom.xml文件引入如下的依赖。

	
        
            cglib
            cglib
            3.2.12
        
    

拦截类说明和创建
创建一个拦截器类CglibMethodInterceptor,实现接口net.sf.cglib.proxy.MethodInterceptor,对应的方法如下:

public class CglibMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("<<<<<日志收集开始...>>>>>>>");
        Object reuslt = proxy.invokeSuper(obj, args);
        System.out.println("<<<<<日志收集结束...>>>>>>>");
        return reuslt;
    }
}

proxy为代理类,obj为代理对象,args为目标参数。proxy.invokeSuper(obj,args)为执行代理对象的目标方法。method为目标方法。

如果需要使用代理,则编写如下的方法:

public class TestProxy {
    public static void main(String[] args) {
        //System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E:\code");
        CglibMethodInterceptor cglibMethodInterceptor = new CglibMethodInterceptor();
        Enhancer enhancer = new Enhancer();
// 设置代理类的父类
        enhancer.setSuperclass(HelloServiceImpl.class);
// 设置回调对象
        enhancer.setCallback(cglibMethodInterceptor);
// 创建代理对象
        HelloService orderService = (HelloServiceImpl) enhancer.create();
        orderService.hello();
    }
}

Enhancer这里要加入回调拦截器,就是通过setCallback方法进行的,被代理类在setSuperclass来传入的。代理对象通过enhancer#create()方法来创建的。这里可以看到cglib动态代理是通过继承法来进行代理的。那这里底层原理是怎样的,下一节可以展示的。

cglib动态代理原理


如图所示,cglib动态代理生成三个类,第一个的父类才是被代理的类,另外两个是cglib包的enhancer和fastClass的子类。当调用被代理类的方法hello时,走如下的代码:

public final void hello() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$hello
 public Object invokeSuper(Object obj, Object[] args) throws Throwable {
        try {
            init();
            FastClassInfo fci = fastClassInfo;
            return fci.f2.invoke(fci.i2, obj, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }
$Method, CGLIB$emptyArgs, CGLIB$hello
 private static class FastClassInfo
    {
        FastClass f1;
        FastClass f2;
        int i1;
        int i2;
    }
$Proxy); } else { super.hello(); } }

这里MethodInterceptor 是上面的实现子类,它为null则直接执行被代理类对应的方法,如果不为空则执行对应的intercept方法。而fastClass如何调用对应的代理类呢?那请看下面的代码:

public int getIndex(Class[] var1) {
        switch(var1.length) {
        case 0:
            return 0;
        default:
            return -1;
        }
    }

    public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
        HelloServiceImpl var10000 = (HelloServiceImpl)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                var10000.hello();
                return null;
            case 1:
                return new Boolean(var10000.equals(var3[0]));
            case 2:
                return var10000.toString();
            case 3:
                return new Integer(var10000.hashCode());
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

Fastclass类的作用是创建索引机制。他的子类就是上面的第二个,对应生成代码如下:

如果index为0,则执行被代理类的hello。从这里可以看出对应的实现不是通过反射而是通过继承。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5695393.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存