您的位置:首页 > 教育 > 锐评 > 乐平网站建设_站长网站查询_新站优化案例_关键seo排名点击软件

乐平网站建设_站长网站查询_新站优化案例_关键seo排名点击软件

2025/5/16 4:31:00 来源:https://blog.csdn.net/zp357252539/article/details/146590005  浏览:    关键词:乐平网站建设_站长网站查询_新站优化案例_关键seo排名点击软件
乐平网站建设_站长网站查询_新站优化案例_关键seo排名点击软件

动态代理模式实现与对比


1. JDK动态代理(基于接口)

定义:通过 java.lang.reflect.ProxyInvocationHandler 实现代理,必须依赖接口
适用场景:目标对象实现接口,需动态增强方法。

代码示例
// 接口
interface Service {void execute();
}// 目标对象
class RealService implements Service {@Overridepublic void execute() {System.out.println("Executing real service");}
}// 代理处理器(实现InvocationHandler)
class ServiceProxy implements InvocationHandler {private Object target;public ServiceProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before execution");Object result = method.invoke(target, args);System.out.println("After execution");return result;}// 生成代理对象public Object getProxy() {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}
}// 使用示例
public class Main {public static void main(String[] args) {RealService realService = new RealService();ServiceProxy proxy = new ServiceProxy(realService);Service serviceProxy = (Service) proxy.getProxy();serviceProxy.execute();}
}

注释说明

  • ServiceProxy 实现 InvocationHandler,通过 invoke() 方法拦截目标方法。
  • Proxy.newProxyInstance() 生成代理对象,必须传入接口列表。
  • 输出:
    Before execution
    Executing real service
    After execution
    

2. CGLIB动态代理(基于继承)

定义:通过继承目标类实现代理,无需接口
适用场景:目标对象未实现接口,需动态增强方法。

代码示例
// 目标类(无接口)
class RealService {public void execute() {System.out.println("Executing real service");}
}// 代理增强类(实现MethodInterceptor)
class ServiceInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before execution");Object result = proxy.invokeSuper(obj, args); // 调用父类方法System.out.println("After execution");return result;}
}// 使用示例
public class Main {public static void main(String[] args) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(RealService.class);enhancer.setCallback(new ServiceInterceptor());RealService serviceProxy = (RealService) enhancer.create();serviceProxy.execute();}
}

注释说明

  • Enhancer 创建代理对象,通过 setSuperclass() 指定目标类。
  • MethodInterceptor 实现 intercept() 方法,通过 invokeSuper() 调用原方法。
  • 输出:
    Before execution
    Executing real service
    After execution
    

3. Spring AOP动态代理

定义:Spring整合JDK和CGLIB,自动选择代理方式。
适用场景:AOP编程,统一管理横切关注点(如日志、事务)。

代码示例
// 接口
interface Service {void execute();
}// 目标类
@Service
class RealService implements Service {@Overridepublic void execute() {System.out.println("Executing real service");}
}// 切面类(使用@Aspect)
@Aspect
@Component
class LoggingAspect {@Around("execution(* com.example.service.*.*(..))")public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Before execution");Object result = joinPoint.proceed();System.out.println("After execution");return result;}
}// 配置类
@Configuration
@EnableAspectJAutoProxy
class AppConfig {@Beanpublic RealService realService() {return new RealService();}
}// 测试类
public class Main {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);Service service = context.getBean(RealService.class);service.execute();}
}

注释说明

  • Spring自动选择JDK或CGLIB代理(有接口用JDK,无接口用CGLIB)。
  • @Aspect@Around 注解定义切面和环绕通知。
  • 输出与前两种代理一致。

对比表格

实现方式原理依赖接口适用场景性能优缺点
JDK动态代理通过 Proxy 类生成代理类,继承 InvocationHandler需要目标对象实现接口的场景(如Spring AOP的接口服务)。较高(接口调用开销小)。实现简单,但无法代理无接口类。
CGLIB代理通过生成目标类的子类,重写所有方法。不需要目标对象未实现接口的场景(如无接口的实体类)。较低(反射生成子类,性能稍差)。支持无接口类,但无法代理 final 方法或类。
Spring AOP自动选择JDK或CGLIB,通过注解简化代理配置。自动判断需要AOP统一管理日志、事务等横切关注点。根据代理方式而定。高度集成Spring,但需依赖框架。

关键区别

维度JDK动态代理CGLIB代理
生成方式通过 Proxy 类生成代理类,继承 InvocationHandler通过字节码生成目标类的子类,重写所有非 final 方法。
性能更快(接口调用直接通过反射)。较慢(需生成子类,反射调用 MethodProxy)。
适用性必须有接口。无需接口,但无法代理 final 方法或类。
Spring集成默认优先选择(当有接口时)。当无接口时自动选择。

总结

  • 选择JDK动态代理:目标对象实现接口,追求高性能。
  • 选择CGLIB代理:目标对象无接口,或需增强 final 方法(Spring Boot默认启用)。
  • Spring AOP:通过注解自动选择代理方式,推荐用于AOP场景。

通过动态代理,可以灵活实现日志、事务、权限等横切逻辑,提升代码的可维护性和扩展性。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com