CGLib动态代理使用与原理

前言

Java中代理有静态代理、动态代理,动态代理中又分JDK动态代理和CGLib动态代理

本文讲一下CGLib动态代理的使用和源码实现,

CGLib动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截,拦截所有父类方法的调用,顺势织入横切逻辑。比使用java反射的JDK动态代理要快

基于jdk1.8.0_161,spring-core5.2.8RELEASE

附上其他两种代理的博文
Java静态代理

JDK动态代理原理 源码详解

CGLib简介

一、什么是CGLIB?

CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。

二、CGLIB原理

CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。

CGLIB底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

CGLIB缺点:对于final方法,无法进行代理。

三、CGLIB的应用

广泛的被许多AOP的框架使用,例如Spring
AOP和dynaop。Hibernate使用CGLIB来代理单端single-ended(多对一和一对一)关联。

扫描二维码关注公众号,回复: 12326961 查看本文章

使用

步骤

1.新建被代理类

2.新建MethodInterceptor接口的实现类,Override intercept方法

3.使用Enhancer生成动态代理

代码

为了方便,上述步骤的接口、类都写到一个类下面

package com.jaylin.jaylin.proxy;

import java.lang.reflect.Method;
import org.springframework.cglib.core.DebuggingClassWriter;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class CglibProxyTest {
    
    
    //被代理类
    static class TestClass {
    
    
        public void testMethod() {
    
    
            System.out.println("testMethod execute");
        }
    }

    static class MyInterceptor implements MethodInterceptor {
    
    
        //使用Enhancer生成动态代理
        public static void main(String[] args) {
    
    
            //设置代理类生成目录,方便查看
            System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\proxy");
            //Enhancer用于生成动态子类以启用方法拦截
            Enhancer enhancer = new Enhancer();
            //设置父类,Cglib基于父类生成代理子类
            enhancer.setSuperclass(TestClass.class);
            //设置回调、拦截处理
            enhancer.setCallback(new MyInterceptor());
            //创建代理类
            TestClass proxyClass = (TestClass) enhancer.create();
            //调用代理类的方法
            proxyClass.testMethod();
        }

        @Override
        public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
    
            Object result = methodProxy.invokeSuper(obj, objects);
            return result;
        }
    }
}

源码解读

Spring | Aop核心 | Cglib源码详细解析 讲得很好,我不想讲了

参考:

java中的三种代理模式

Spring | Aop核心 | Cglib源码详细解析

CGLIB介绍与原理

CGLIB(Code Generation Library)详解

猜你喜欢

转载自blog.csdn.net/weixin_43859729/article/details/109048922