Java 动态代理

发布时间:2026/5/18 23:31:49

Java 动态代理 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 以及许多 Java 框架中常见的两种动态代理方式它们在实现方式、使用场景和性能上有所不同。JDK 动态代理依赖java.lang.reflect.Proxy和InvocationHandler进行代理只能代理接口不能直接代理具体类基于 Java 反射在运行时生成代理类目标类必须实现接口使用Proxy.newProxyInstance()生成代理对象代理方法调用时委托给InvocationHandler处理importjava.lang.reflect.*;interfaceService{voiddoSomething();}classRealServiceimplementsService{publicvoiddoSomething(){System.out.println(真实业务逻辑执行);}}classMyInvocationHandlerimplementsInvocationHandler{privatefinalObjecttarget;publicMyInvocationHandler(Objecttarget){this.targettarget;}OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println(JDK 代理 - 方法执行前);Objectresultmethod.invoke(target,args);System.out.println(JDK 代理 - 方法执行后);returnresult;}}publicclassJDKProxyTest{publicstaticvoidmain(String[]args){ServicetargetnewRealService();Serviceproxy(Service)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),newMyInvocationHandler(target));proxy.doSomething();}}CGLIB 动态代理依赖ASM 字节码技术通过继承目标类创建子类代理可以代理普通类不需要实现接口基于子类代理无法代理final类或final方法importnet.sf.cglib.proxy.*;classRealService{publicvoiddoSomething(){System.out.println(真实业务逻辑执行);}}classMyMethodInterceptorimplementsMethodInterceptor{OverridepublicObjectintercept(Objectobj,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{System.out.println(CGLIB 代理 - 方法执行前);Objectresultproxy.invokeSuper(obj,args);System.out.println(CGLIB 代理 - 方法执行后);returnresult;}}publicclassCGLIBProxyTest{publicstaticvoidmain(String[]args){EnhancerenhancernewEnhancer();enhancer.setSuperclass(RealService.class);enhancer.setCallback(newMyMethodInterceptor());RealServiceproxy(RealService)enhancer.create();proxy.doSomething();}}性能比 JDK 代理更高直接操作字节码无需反射Spring AOP默认选择 JDK 动态代理除非目标类没有实现接口才会使用 CGLIB如果希望 Spring强制使用 CGLIB可以EnableAspectJAutoProxy(proxyTargetClasstrue)在实际开发中如果业务主要是接口编程如 Service 层JDK 代理更合适如果需要代理普通类如工具类CGLIB 是更好的选择

相关新闻