JDK动态代理和CGLib动态代理

本文介绍了JDK动态代理的原理,包括获取被代理对象接口、生成新类并实现接口、动态生成代码、编译及加载到JVM。接着讲解了CGLib动态代理,它通过继承被代理对象并利用ASM框架写Class字节码,虽然效率低于JDK,但调用方法时使用FastClass机制,执行效率更高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,JDK动态代理原理:

1.步骤:

(1):获取被代理对象的引用,并且获取它的所有接口,反射获取

(2):JDK动态代理类重新生成一个新的类,同时新的类要实现被代理类的所有接口

(3):动态生成Java代码,新加的业务逻辑方法由一定的逻辑代码调用(在代码中体现)

(4):编译新生成的Java代码.class文件

(5):重新加载到JVM中运行

以上过程叫字节码重组。JDK有一个规范,在ClassPath下只要是以$开头的.class文件一般都是生成的。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * test.JDKProxy
 * Description:
 * date:3/28/2022 4:32 PM
 *
 * @author:chenweipeng
 * @version:1.0
 * @since JDK 1.8
 */
interface IPerson{
    void findLove(String name);
}

class ZhaoLiu implements IPerson{

    @Override
    public void findLove(String name) {
        System.out.print("找到了"+name);
        System.out.println("符合赵六的标准");
    }
}

public class JDKProxy implements InvocationHandler {

    private Object target;

    public Object getProxyObject(Object target){
        this.target = target;
        Class<?> clazz = target.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object invoke = method.invoke(this.target, args);
        after();
        return invoke;
    }

    private void before(){
        System.out.println("before");
    }

    private void after(){
        System.out.println("after");
    }
}

class Test08{
    public static void main(String[] args) {
       IPerson person = ((IPerson) (new JDKProxy().getProxyObject(new ZhaoLiu())));
       person.findLove("凤姐");
    }
}
before
找到了凤姐符合赵六的标准
after

二、CGLib动态代理

(1)JDK动态代理实现了被代理对象的接口,CGLib动态代理继承了被代理对象

(2)JDK动态代理和CGLib动态代理都在运行期间生成字节码,JDK动态代理直接写Class字节码,CGLib动态代理使用ASM框架写Class字节码。CGLib动态代理更加复杂,生成代理类的效率比JDK动态代理低

(3)JDK动态代理调用代理方法是通过反射机制调用的,CGLib动态代理使用过FastClass机制直接调用方法的,CGLib动态代理的执行效率更高

依赖:

<dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.10.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
        <dependency>
            <groupId>org.ow2.asm</groupId>
            <artifactId>asm</artifactId>
            <version>7.1</version>
            </dependency>
package test;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * test.CGlibMeipo
 * Description:
 * date:3/28/2022 5:01 PM
 *
 * @author:chenweipeng
 * @version:1.0
 * @since JDK 1.8
 */
public class CGlibMeipo implements MethodInterceptor {

    //private Object target;

    public Object getInstance(Object o){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(o.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        before();
        Object o1 = methodProxy.invokeSuper(o, objects);
        after();
        return o1;
    }

    private void before(){
        System.out.println("before");
    }

    private void after(){
        System.out.println("after");
    }
}

class Customer{
    public void findLove(){
        System.out.println("doing...");
    }
}

class Test09{
    public static void main(String[] args) {
        ((Customer) new CGlibMeipo().getInstance(new Customer())).findLove();
    }
}
before
doing...
after

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值