** 基于字节码直接操作,**原生提供动态代理、方法拦截能力**)
JavassistJava 编程助手基于字节码直接操作原生提供动态代理、方法拦截能力对比 JDK 动态代理、CGLIB✅ 优势不用手写接口、不用手动实现 MethodInterceptor 样板代码可以直接构造拦截逻辑底层自动生成代理类字节码极简实现AOP拦截。注意区分JDK Proxy只能代理接口必须实现InvocationHandlerCGLIB继承子类代理需要MethodInterceptorJavassist两种方案①简易ProxyFactory开箱即用拦截②手动CtClass字节码构建。一、Javassist ProxyFactory内置动态代理自动拦截javassist.util.proxy.ProxyFactory是官方封装好的动态代理工具自动生成子类代理类内置拦截器接口不需要手动拼接字节码。关键接口// 方法拦截器回调所有被代理方法执行publicinterfaceMethodFilter{booleanisHandled(Methodm);// 过滤需要拦截的方法}publicinterfaceMethodHandler{// 执行拦截逻辑Objectinvoke(Objectself,MethodthisMethod,Methodproceed,Object[]args)throwsThrowable;}self代理对象thisMethod原始方法proceed调用原方法核心执行目标逻辑最简示例无需手动编写字节码Maven依赖dependencygroupIdorg.javassist/groupIdartifactIdjavassist/artifactIdversion3.29.2-GA/version/dependencyimportjavassist.util.proxy.MethodHandler;importjavassist.util.proxy.ProxyFactory;importjava.lang.reflect.Method;// 目标类普通类不需要实现接口classUserService{publicvoidsayHello(Stringname){System.out.println(Hello:name);}}publicclassJavassistProxyDemo{publicstaticvoidmain(String[]args)throwsException{// 1. 创建代理工厂ProxyFactoryfactorynewProxyFactory();factory.setSuperclass(UserService.class);// 设置父类实现类代理factory.setFilter(m-true);// 拦截所有方法// 2. 生成代理ClassClass?proxyClsfactory.createClass();UserServiceproxy(UserService)proxyCls.newInstance();// 3. 设置拦截器核心自动拦截方法调用((javassist.util.proxy.Proxy)proxy).setHandler(newMethodHandler(){OverridepublicObjectinvoke(Objectself,MethodthisMethod,Methodproceed,Object[]args)throwsThrowable{System.out.println(【前置拦截】方法开始thisMethod.getName());// 执行原始方法Objectresultproceed.invoke(self,args);System.out.println(【后置拦截】方法结束);returnresult;}});// 调用方法自动触发拦截proxy.sayHello(test);}}运行输出【前置拦截】方法开始sayHello Hello:test 【后置拦截】方法结束二、为什么说「内部自动实现动态代理无需手动编码」自动生成代理字节码ProxyFactory.createClass()底层使用 Javassist 的CtClass自动构造子类继承目标类重写所有非final方法方法内部预埋拦截器调用逻辑开发者不需要手写CtMethod、不需要拼接字节码指令。统一拦截器入口所有被重写的方法会自动转发到MethodHandler.invoke()统一拦截点不用为每个方法单独编写代理转发代码。支持普通类代理不需要接口对比JDK动态代理强制要求接口Javassist ProxyFactory 类似CGLIB支持代理普通实体类。三、两种使用模式对比模式编码量适用场景ProxyFactory推荐极少只写拦截逻辑通用AOP、动态代理业务开发题目描述对应的方案原生CtClass手动字节码大量底层代码自定义复杂字节码改造、框架底层增强你题干描述“内部自动实现动态代理与拦截器无需手动编码”特指ProxyFactory这套封装不是原始CtClass底层API。四、和CGLIB核心差异CGLIB底层ASMJavassist自身字节码编译器语法更贴近Java源码Javassist可以源码级字符串编写字节码CtMethod.setBody({...})ProxyFactory自带拦截器封装上手更简单Spring早期同时兼容CGLIB/Javassist新版本默认CGLIB。五、重要注意事项不能代理final类、final方法无法继承重写代理对象默认是空参构造实例化目标类若无空构造需要使用create(构造参数)Javassist生成类默认加载到当前ClassLoader频繁动态生成类容易造成元空间溢出MethodHandler中proceed.invoke()是调用原始逻辑不要直接调用目标对象方法会造成递归死循环。六、拓展如果是底层原生CtClass方式需要手动编码不属于题干场景直接操作CtClass需要手动重写方法、植入拦截代码属于底层API不符合“无需手动编码”框架一般不会直接使用这套做通用代理仅用于特殊字节码增强。如果你需要我可以补充Javassist实现类似Spring AOP的简易切面封装ProxyFactory 源码简要分析自动生成代理类的流程Javassist 动态代理常见报错解决方案。