【大白话说Java面试题】【Java基础篇】第28题:Java代理有哪几种实现方式
2026/5/5 2:58:47 网站建设 项目流程
第28题:Java代理有哪几种实现方式

📚回答:

Java代理主要有两种实现方式:静态代理动态代理。其中,动态代理又分为JDK动态代理CGLIB动态代理


1. 静态代理
  • 定义
    静态代理是指在编码阶段就明确目标对象和代理对象的关系,两者实现相同的接口或继承相同的父类。

  • 特点

    • 优点
      • 实现简单,容易理解。
      • 能够在不修改目标对象的前提下,通过代理对象扩展功能(如日志记录、权限校验等)。
    • 缺点
      • 如果接口增加方法,目标对象和代理对象都需要同步维护,代码冗余严重。
      • 代理类与目标类耦合度高,灵活性差。

💡代码示例
以下代码展示了静态代理的基本实现:

interfaceService{voidexecute();}classTargetServiceimplementsService{@Overridepublicvoidexecute(){System.out.println("目标对象执行业务逻辑");}}classStaticProxyimplementsService{privateServicetarget;publicStaticProxy(Servicetarget){this.target=target;}@Overridepublicvoidexecute(){System.out.println("代理对象:前置处理");target.execute();System.out.println("代理对象:后置处理");}}publicclassMain{publicstaticvoidmain(String[]args){Servicetarget=newTargetService();Serviceproxy=newStaticProxy(target);proxy.execute();}}

2. 动态代理
  • 定义
    动态代理是在程序运行时动态生成代理对象,而不需要在编码阶段确定代理类与目标类的关系。

  • 分类

    • JDK动态代理:基于接口实现,要求目标对象必须实现接口。
    • CGLIB动态代理:基于继承实现,适用于没有实现接口的目标对象。

💡代码示例

JDK动态代理:
importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;interfaceService{voidexecute();}classTargetServiceimplementsService{@Overridepublicvoidexecute(){System.out.println("目标对象执行业务逻辑");}}classDynamicProxyHandlerimplementsInvocationHandler{privateObjecttarget;publicDynamicProxyHandler(Objecttarget){this.target=target;}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("代理对象:前置处理");Objectresult=method.invoke(target,args);System.out.println("代理对象:后置处理");returnresult;}}publicclassMain{publicstaticvoidmain(String[]args){Servicetarget=newTargetService();Serviceproxy=(Service)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),newDynamicProxyHandler(target));proxy.execute();}}
CGLIB动态代理:
importorg.springframework.cglib.proxy.Enhancer;importorg.springframework.cglib.proxy.MethodInterceptor;importorg.springframework.cglib.proxy.MethodProxy;classTargetService{publicvoidexecute(){System.out.println("目标对象执行业务逻辑");}}classCglibProxyimplementsMethodInterceptor{@OverridepublicObjectintercept(Objectobj,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{System.out.println("代理对象:前置处理");Objectresult=proxy.invokeSuper(obj,args);System.out.println("代理对象:后置处理");returnresult;}}publicclassMain{publicstaticvoidmain(String[]args){Enhancerenhancer=newEnhancer();enhancer.setSuperclass(TargetService.class);enhancer.setCallback(newCglibProxy());TargetServiceproxy=(TargetService)enhancer.create();proxy.execute();}}

💡面试官视角

  • 面试官可能会问“JDK动态代理和CGLIB动态代理的区别是什么?”
    答:JDK动态代理基于接口实现,要求目标对象必须实现接口;CGLIB基于继承实现,适用于没有实现接口的目标对象,但无法代理final类或final方法。
  • 面试官可能会追问“Spring框架中如何选择使用哪种动态代理?”
    答:如果目标对象实现了接口,优先使用JDK动态代理;否则使用CGLIB动态代理。

📌专栏:大白话说Java面试题 — 01-Java基础篇

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询