代理模式在java中主要有四种实现方式。1. 静态代理需手动编写代理类,通过持有目标类引用并添加额外逻辑,适合小规模项目但代码冗余;2. jdk动态代理基于接口,利用proxy和invocationhandler在运行时生成代理对象,灵活但仅限接口代理;3. cglib代理通过继承目标类并重写方法实现,可代理无接口类,适用范围广但无法处理final类或方法;4. spring aop根据目标类是否实现接口自动选择jdk或cglib代理,也可强制使用cglib,使开发者无需关注底层实现。
代理模式在Java中是一种常见的设计模式,主要用于控制对象的访问、增强功能或延迟加载。它通过一个代理类来间接操作目标对象,常用于AOP编程、远程调用(RMI)、权限控制等场景。
Java中实现代理的方式有多种,下面从常见且实用的角度出发,分别介绍几种主流的代理实现方式。
静态代理是最基础也是最容易理解的一种代理方式。它的特点是需要为每一个目标类手动编写一个对应的代理类。
立即学习“Java免费学习笔记(深入)”;
实现步骤如下:
举个例子:
public interface Service { void doSomething(); } public class RealService implements Service { public void doSomething() { System.out.println("Doing something..."); } } public class StaticProxy implements Service { private Service target; public StaticProxy(Service target) { this.target = target; } public void doSomething() { System.out.println("Before method call"); target.doSomething(); System.out.println("After method call"); } }
这种方式优点是结构清晰,缺点是代码冗余,每增加一个服务都需要一个新的代理类。
JDK动态代理是Java自带的功能,利用java.lang.reflect.Proxy类和InvocationHandler接口实现在运行时动态创建代理对象。
关键点在于:
示例代码:
Service proxy = (Service) Proxy.newProxyInstance( Service.class.getClassLoader(), new Class[]{Service.class}, new InvocationHandler() { private Object target = new RealService(); public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("JDK Proxy: before"); Object result = method.invoke(target, args); System.out.println("JDK Proxy: after"); return result; } } ); proxy.doSomething();
这种方式的优点是灵活性高,无需手动编写代理类。但局限也很明显:只能对接口进行代理,不能代理没有实现接口的类。
CGLIB是一个强大的第三方库,它通过继承目标类并重写其方法的方式来生成代理类,因此可以代理没有实现接口的类。
使用CGLIB的关键组件是Enhancer类和MethodInterceptor接口。
基本流程如下:
简单示例:
Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealService.class); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("CGLIB Proxy: before"); Object result = proxy.invokeSuper(obj, args); System.out.println("CGLIB Proxy: after"); return result; } }); RealService proxy = (RealService) enhancer.create(); proxy.doSomething();
CGLIB适用于更广泛的场景,尤其适合Spring这类框架中默认使用的代理机制。但要注意的是,不能代理final类和final方法。
在实际开发中,我们经常使用Spring AOP来实现日志记录、事务管理等功能。Spring底层会根据目标类是否实现了接口来自动选择使用JDK动态代理还是CGLIB代理。
Spring的判断逻辑大致如下:
当然你也可以强制Spring始终使用CGLIB代理,只需在配置中设置:
<aop:config proxy-target-class="true"/>
或者在注解驱动下启用:
@EnableAspectJAutoProxy(proxyTargetClass = true)
这种机制让开发者不需要关心底层代理是如何构建的,只需要专注于切面逻辑的编写即可。
总的来说,Java中代理模式的实现方式各有适用场景。静态代理适合小规模项目或教学用途;JDK动态代理和CGLIB代理则更适合实际开发中灵活扩展的需求;而Spring在此基础上进一步封装,使得代理机制对开发者透明化。
基本上就这些。
以上就是Java中代理模式的几种实现方式详细技术解析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号