• CGLib动态代理


    代理即为访问对象添加一层控制层,使其间接化,控制层可以为对象访问添加操作属性。

    CGLib:Code Generation Library。

    使用JDK创建代理有一个限制,即它要求被代理对象实现了某一个或某些接口,如果被代理对象没有实现接口,可以使用CGLib实现动态代理~

    CGLib采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并织入横切逻辑。

    maven坐标:

    <!-- https://mvnrepository.com/artifact/cglib/cglib -->
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.4</version>
    </dependency>
    • 基于ASM(java字节码操作码)的高性能代码生成包
    • 被许多AOP框架使用
    • 区别于JDK动态代理,cglib不需要被代理对象实现接口。
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class CglibProxy implements MethodInterceptor {
        private Enhancer enhancer = new Enhancer();
    
        public Object createProxyInstance(Class clazz) {
            //设置需要创建子类的类
            enhancer.setSuperclass(clazz);
            enhancer.setCallback(this);
            //使用字节码技术动态创建子类实例
            return enhancer.create();
        }
    
        /**
         * 拦截父类所有方法的调用
         * @param obj         目标类的实例
         * @param method      目标类方法的反射对象
         * @param args        方法参数
         * @param proxy       代理对象
         * @return
         * @throws Throwable
         */
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("执行实例方法前的横切逻辑");
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("执行实例方法后的横切逻辑");
            return result;
        }
    }

    测试 

    public class Client {
        public static void main(String[] args) {
            //创建代理对象
            RealSubject subject = (RealSubject) new CglibProxy().createProxyInstance(RealSubject.class);
            //执行方法(使用的是代理对象)
            //生成代理对象之后,调用request方法,subject只是一个代理对象
            subject.request();
            System.out.println("代理类:" + subject);
        }
    }

    执行结果:

    执行实例方法前的横切逻辑
    From real subject.
    执行实例方法后的横切逻辑
    代理类:RealSubject$$EnhancerByCGLIB$$564b4e3e@32a1bec0
    RealSubject$$EnhancerByCGLIB$$564b4e3e@32a1bec0就是CGLib为RealSubject动态创建的代理子类

    因为CGLib使用动态创建子类的方式生成代理对象,所以不能对目标类中的final或private方法进行代理! 

  • 相关阅读:
    【深入理解Java虚拟机】类加载机制
    【深入理解Java虚拟机】四种引用类型的特点
    【深入理解Java虚拟机】JVM内存区域
    【每日一题】单词搜索
    过滤器和拦截器有啥区别,这次会了!
    Filter过滤器简单入门
    SpringMVC的运行流程+常用注解总结
    SpringAOP+源码解析,切就完事了
    Spring的循环依赖,学就完事了【附源码】
    Markdown的流程图制作
  • 原文地址:https://www.cnblogs.com/winner-0715/p/6010870.html
Copyright © 2020-2023  润新知