当前位置: 首页 > 图灵资讯 > 技术篇> spring动态代理为什么没有用javassist

spring动态代理为什么没有用javassist

来源:图灵教育
时间:2023-08-11 11:07:09

为什么Spring动态代理不使用Javassist简介?

在讨论Spring动态代理为什么不使用Javassist之前,让我们先了解一下动态代理和Javassist的概念。

动态代理是一种在运行过程中生成代理对象的技术,它允许我们在不修改原始代码的情况下增强或拦截方法。动态代理用于实现Spring框架中的AOP(面向切面编程)功能,以增加一些共同的横向关注点,如日志、事务等,而不改变业务逻辑。

Javassist是Java字节码编辑器,它为操作字节码提供了更高级别的API。Javassist比Java反射更简单易用,性能更好。

现在,让我们来分析一下为什么Spring动态代理不使用Javassist。

流程图
st=>start: 开始op1=>operation: 创建目标对象op2=>operation: op3选择代理模式=>operation: OP4生成代理对象=>operation: 执行增强逻辑op5=>operation: 返回结果e=>end: 结束st->op1->op2->op3->op4->op5->e
具体步骤

下面我们将详细介绍整个过程的每一步需要做什么,以及需要使用的代码。

  1. 要创建目标对象:首先要创建目标对象,即要被代理的对象。您可以使用以下代码创建一个简单的目标对象:
public class TargetObject {    public void doSomething() {        // 目标方法的逻辑    }}
  1. 选择代理:Spring框架提供两种动态代理方法,即基于界面的JDK动态代理和基于类别的CGLib动态代理。根据需要选择其中一种方法。通常,如果目标对象实现界面,则使用JDK动态代理;如果目标对象没有实现界面,则使用CGLib动态代理。

  2. 生成代理对象:根据选定的代理方法,使用相应的代码生成代理对象。

    • JDK动态代理:
    public class JDKProxy implements InvocationHandler {    private Object target; // 目标对象     public JDKProxy(Object target) {        this.target = target;    }     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        // 增强逻辑        Object result = method.invoke(target, args);        // 增强逻辑        return result;    }     public Object getProxy() {        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);    }}
    • CGLib动态代理:
    public class CGLibProxy implements MethodInterceptor {    private Object target; // 目标对象     public CGLibProxy(Object target) {        this.target = target;    }     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {        // 增强逻辑        Object result = proxy.invoke(target, args);        // 增强逻辑        return result;    }     public Object getProxy() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(target.getClass());        enhancer.setCallback(this);        return enhancer.create();    }}
  3. 执行增强逻辑:在生成的代理对象中重写invoke方法(JDK动态代理)或intercept方法(CGLib动态代理)实现增强逻辑。可在方法执行前后或异常处理时增强。

  4. 返回结果:最后,返回代理对象作为目标对象的替代品,以便在外部代码中使用。

结论

选择不使用Javassist作为动态代理的Spring框架主要有以下原因:

  • 性能:Javassist在生成字节码的过程中,需要对Java字节码进行分析和修改,并进行动态加载。相比之下