Spring中的代理ProxyFactory解析

 更新时间:2023年12月25日 11:43:51   作者:努力中的少年  
这篇文章主要介绍了Spring中的ProxyFactory解析,在Java中,代理模式的实现通常依靠Proxy类和InvocationHandler接口,本文将介绍如何使用ProxyFactory来创建代理模式,需要的朋友可以参考下

前言

当涉及到Java程序员们谈论面向对象编程的时候,代理模式总是一个热门话题。代理模式在许多场景下都有用武之地,比如日志记录、事务管理、权限验证等等。

而在Java中,代理模式的实现通常依靠Proxy类和InvocationHandler接口。本文将介绍如何使用ProxyFactory来创建代理模式。

什么是代理模式?

在计算机科学中,代理模式是一种结构型设计模式,它可以为其他对象提供一个替代品或者占位符,以控制对这个对象的访问。

代理对象通常充当了客户端和目标对象之间的中介,从而可以隐藏目标对象的实现细节、保护目标对象不被非法访问、增强目标对象的功能等等。

代理模式有两种形式:静态代理和动态代理。静态代理的优点是能够提前做好一些工作,例如参数的检查、日志记录等等;

缺点则是需要针对每个需要代理的接口编写一个代理类。而动态代理则可以根据接口生成代理对象,并且可以在运行时动态的添加和修改代理方法,因此更加灵活。

了解Proxy和InvocationHandler

在Java中,代理模式的实现主要依靠了Proxy类和InvocationHandler接口。其中,Proxy类是生成代理类的主要工具,而InvocationHandler则是提供对代理方法的具体实现。

Proxy类有两个静态方法可以用来创建代理对象:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

该方法用于创建一个动态代理对象,参数loader表示ClassLoader、interfaces表示实现的接口列表、h表示InvocationHandler。

public static Object newProxyInstance(Class<?> clazz, InvocationHandler h)

该方法用于创建一个指定类的代理对象,参数clazz表示需要代理的类、h表示InvocationHandler。

而InvocationHandler接口则是定义了一个统一的代理方法:

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

在代理模式中,当我们调用代理对象的方法时,实际上会调用InvocationHandler的invoke()方法,在这个方法中,我们可以根据需要进行一些操作,并返回目标对象的执行结果。

使用ProxyFactory创建动态代理

在Java中,如果要使用动态代理,首先需要创建一个InvocationHandler实现类。例如,下面是一个简单的InvocationHandler实现类:

public class MyInvocationHandler implements InvocationHandler {
    private Object target;
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before calling " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After calling " + method.getName());
        return result;
    }
}

这个InvocationHandler实现类接受一个代理对象的目标对象,然后在代理方法被调用前输出一行日志,在返回结果之前再输出一行日志。

然后我们可以通过ProxyFactory来创建一个动态代理对象。ProxyFactory是一个通用的代理工厂,它提供了很多便捷的方法来创建不同类型的代理。例如下面的代码演示了如何使用ProxyFactory来创建一个JDK动态代理:

public class ProxyTest {
    public static void main(String[] args) {
        // 创建目标对象
        HelloService helloService = new HelloServiceImpl();
        // 创建InvocationHandler实例
        InvocationHandler invocationHandler = new MyInvocationHandler(helloService);
        // 创建代理对象
        HelloService proxy = (HelloService) ProxyFactory.getProxy(helloService.getClass, invocationHandler);
    // 调用代理对象的方法
    proxy.sayHello("Jack");
}
}

在上面的代码中,我们首先创建了一个目标对象HelloServiceImpl。然后创建了一个InvocationHandler实例,并将HelloServiceImpl作为它的参数传递进去。最后通过调用ProxyFactory的getProxy()方法来生成一个动态代理对象proxy。在调用proxy的sayHello()方法时,实际上会调用MyInvocationHandler的invoke()方法,在这个方法中输出日志并调用HelloServiceImpl的sayHello()方法,最终返回结果。

使用ProxyFactory创建Cglib动态代理

除了JDK动态代理之外,还有一种常见的动态代理实现方式是使用Cglib库。与JDK动态代理不同,Cglib动态代理可以代理非接口类型的类。

下面我们演示如何使用ProxyFactory来创建一个Cglib动态代理:

public class ProxyTest {
    public static void main(String[] args) {
        // 创建目标对象
        UserDaoImpl userDao = new UserDaoImpl();
        // 创建MethodInterceptor实例
        MethodInterceptor methodInterceptor = new MyMethodInterceptor(userDao);
        // 创建代理对象
        UserDaoImpl proxy = (UserDaoImpl) ProxyFactory.getProxy(userDao.getClass(), methodInterceptor);
        // 调用代理对象的方法
        proxy.save();
    }
}
class UserDaoImpl {
    public void save() {
        System.out.println("Saving user...");
    }
}
class MyMethodInterceptor implements MethodInterceptor {
    private Object target;
    public MyMethodInterceptor(Object target) {
        this.target = target;
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before calling " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After calling " + method.getName());
        return result;
    }
}

在这个例子中,我们创建了一个UserDaoImpl类,并为它创建了一个MethodInterceptor实现类。

然后通过调用ProxyFactory的getProxy()方法来生成一个Cglib动态代理对象proxy。

在调用proxy的save()方法时,实际上会调用MyMethodInterceptor的intercept()方法,在这个方法中输出日志并调用UserDaoImpl的save()方法,最终返回结果。

总结

本文介绍了如何使用ProxyFactory来创建动态代理,包括JDK动态代理和Cglib动态代理。

通过使用ProxyFactory,可以更加方便地创建代理对象,并且可以根据需要自定义不同类型的代理行为。

虽然动态代理不是解决所有问题的万能工具,但在某些场景下,它仍然是一种非常强大和有用的设计模式。

到此这篇关于Spring中的代理ProxyFactory解析的文章就介绍到这了,更多相关Spring的ProxyFactory内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot 注解方式批量插入数据的实现

    springboot 注解方式批量插入数据的实现

    一次请求需要往数据库插入多条数据时,可以节省大量时间,本文主要介绍了springboot 注解方式批量插入数据,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java中的ReentrantLock、ReentrantReadWriteLock、StampedLock详解

    Java中的ReentrantLock、ReentrantReadWriteLock、StampedLock详解

    这篇文章主要介绍了Java中的ReentrantLock、ReentrantReadWriteLock、StampedLock详解,读写锁:一个资源能够被多个读线程访问,或者被一个写线程访问但是不能同时存在读写线程,需要的朋友可以参考下
    2024-01-01
  • Eclipse快捷键使用小结

    Eclipse快捷键使用小结

    Eclipse是用java的同行必不可少的工具,我总结了一下它的快捷键,太常用的ctrl+单击、ctrl+shift+F、Ctrl+1等我就不细说了,主要是方便查看。下边小编就详细的为大家介绍一下
    2013-07-07
  • java基础之反射和泛型以及注解

    java基础之反射和泛型以及注解

    这篇文章主要介绍了 java基础之反射和泛型以及注解的相关资料,需要的朋友可以参考下
    2017-07-07
  • Java网络编程之简易聊天室的实现

    Java网络编程之简易聊天室的实现

    这篇文章主要为大家详细介绍了如何利用Java语言实现一个简易聊天室功能,可以实现运行客户端和连接服务器,文中的示例代码讲解详细,需要的可以了解一下
    2022-10-10
  • Lombok基本注解之@SneakyThrows的作用

    Lombok基本注解之@SneakyThrows的作用

    @SneakyThrows注解是由lombok为咱们封装的,它能够为咱们的代码生成一个try...catch块,并把异常向上抛出来,下面这篇文章主要给大家介绍了关于Lombok基本注解之@SneakyThrows作用的相关资料,需要的朋友可以参考下
    2022-01-01
  • JAVA正则表达式匹配多个空格的解决方案

    JAVA正则表达式匹配多个空格的解决方案

    这篇文章主要介绍了JAVA正则表达式匹配多个空格的解决方案,文中提到了()和[]本质的区别,本文给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11
  • Java并发编程之原子变量与非阻塞同步机制

    Java并发编程之原子变量与非阻塞同步机制

    这篇文章主要介绍了Java并发编程之原子变量与非阻塞同步机制,本文讲解了非阻塞算法、悲观技术、乐观技术、CAS操作、原子变量、性能比较:锁与原子变量等内容,需要的朋友可以参考下
    2015-04-04
  • 详解Java sort()数组排序(升序和降序)

    详解Java sort()数组排序(升序和降序)

    这篇文章主要介绍了详解Java sort()数组排序(升序和降序),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • java 判断字符串是否包含子串的方法

    java 判断字符串是否包含子串的方法

    这篇文章主要介绍了java 判断字符串是否包含子串的方法的相关资料,这里提供了三种方法帮助大家实现这样的功能,需要的朋友可以参考下
    2017-08-08

最新评论