本文共 3046 字,大约阅读时间需要 10 分钟。
代理模式是Java中的常用设计模式之一,其特点是代理类与委托类具有相同的接口,代理类主要负责为委托类提供额外功能,如预处理、过滤、转发消息以及事后处理等。在这种模式中,代理类和委托类之间通常存在关联关系,一个代理类与一个委托类关联,一般情况下,代理类不会直接实现服务,而是通过调用委托类的方法来提供服务。这样一来,程序开发过程中便可以通过不同的代理类灵活配置功能,例如事务处理、日志记录等,从而提高系统的可扩展性和维护性。
在实际应用开发中,单独使用静态代理往往会产生代理类数量过多的问题,因为每个代理类只能为一个接口服务。面对这种情况,一个更灵活且高效的选择便是使用动态代理。接下来我们将详细探讨Java的动态代理实现方式。
JDK动态代理的核心是通过InvocationHandler
接口来实现动态代理的逻辑。InvocationHandler
接口声明了一个方法:
public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;}
这个方法的作用是指定如何对代理对象主动生成方法调用。在实际应用中,我们可以通过实现InvocationHandler
接口,动态代理拦截并调整方法调用行为。
Proxy 类是一个生成动态代理的工具类,主要提供了以下功能:
InvocationHandler
接口的实现来决定。Proxy类的关键方法为:
public static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h) throws IllegalArgumentException
其参数说明如下:
ClassLoader loader
: 拟定的类加载器。Class<?>[] interfaces
: 需要被代理的接口类。InvocationHandler h
: 拦截方法调用的处理逻辑。在调用Proxy.newProxyInstance
方法时,需要提供一个正确的ClassLoader
实例。在Java中,一个主要的ClassLoader
类型包括:
jre\lib\ext
目录。jar
文件中的类加载。如果不特别指定ClassLoader
,Proxy.newProxyInstance
方法会使用目标类的ClassLoader
,这样可以确保绑定类型妥当。
相比于静态代理,动态代理具有以下优势:
除了JDK动态代理,我们还可以使用Cglib动态代理,它旨在代理没有实现接口的具体类。Cglib采用类继承的方式对目标类进行代理,这样 对于实现了final
方法的类也能有效生成代理实例。
Cglib通过生成目标类的子类来实现动态代理,并覆盖目标类中需要 proxy 的方法。这样做的优点是可以直接操作目标类的字段和方法,而缺点是不能代理final修饰的方法。
MethodInterceptor
类,实现Cglib回调接口。Enhancer
工具生成动态代理类。例如,以下是Cglib动态代理的核心代码:
public class MethodInterceptor implements MethodInterceptor { private Object target; public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("事物处理开始"); proxy.invokeSuper(obj, args); System.out.println("事物处理结束"); return null; }}
public class BookImpl { public void addBook() { System.out.println("增加图书"); }}
MethodInterceptor interceptor = new MethodInterceptor();BookImpl book = interceptor.getInstance(new BookImpl());book.addBook();
动态代理技术在以下场景下表现出色:
通过以上内容,我们可以看到,动态代理技术为Java程序的核心逻辑功能增添了强大的灵活性和可扩展性,能够适应复杂的双层业务需求。无论是通过JDK动态代理实现规范化接口代理,还是采用Cglib动态代理实现实例代理,都能为现代Java应用提供优雅而高效的解决方案。
转载地址:http://iwyqz.baihongyu.com/