深入理解Java动态代理与静态代理

深入理解Java动态代理与静态代理

静态代理

静态代理是为了实现被代理对象的方法增强而设计的一种代理方式。其中,被代理的对象接口和代理对象接口相同,代理对象持有被代理对象实例的引用,通过代理对象间接调用被代理对象的方法。静态代理的实现需要手工编写代理类,代理类需要实现被代理的所有接口方法,并在处理这些方法的时候添加额外的逻辑,如日志打印、性能监控、异常捕获等。

以下是一个静态代理的示例:

定义接口:

public interface IUserDao {
    void save();
}

定义被代理类:

public class UserDao implements IUserDao {
    @Override
    public void save() {
        System.out.println("保存用户");
    }
}

定义代理类:

public class UserDaoProxy implements IUserDao {
    private IUserDao userDao;

    public UserDaoProxy(IUserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        System.out.println("开始事务");
        userDao.save();
        System.out.println("提交事务");
    }
}

测试代理:

public class StaticProxyTest {
    public static void main(String[] args) {
        IUserDao userDao = new UserDao();
        UserDaoProxy userDaoProxy = new UserDaoProxy(userDao);
        userDaoProxy.save();
    }
}

输出结果:

开始事务
保存用户
提交事务

动态代理

动态代理是一种在运行时根据接口动态代理方法的类。它可以在运行时动态地创建被代理对象的代理类,并在代理类中实现被代理对象接口的所有方法,动态代理可以有效降低代码的耦合度、简化编码复杂度以及提高代码的可维护性。

动态代理一般通过JDK提供的接口实现,其中,被代理的对象需要实现接口,代理类不需要手工实现,因为在代理类中实现了被代理对象的所有接口方法。一般来说,我们常用的代理类就是JDK动态代理实现的代理类。

以下是一个使用JDK动态代理的示例:

定义接口:

public interface IUserDao {
    void save();
}

定义被代理类:

public class UserDao implements IUserDao {
    @Override
    public void save() {
        System.out.println("保存用户");
    }
}

定义代理类:

public class UserDaoProxy implements InvocationHandler {
    private Object target; // 被代理对象

    public UserDaoProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始事务");
        Object result = method.invoke(target, args);
        System.out.println("提交事务");
        return result;
    }
}

测试代理:

public class DynamicProxyTest {
    public static void main(String[] args) {
        IUserDao userDao = new UserDao();
        InvocationHandler proxy = new UserDaoProxy(userDao);
        ClassLoader classLoader = userDao.getClass().getClassLoader();
        IUserDao userDaoProxy = (IUserDao) Proxy.newProxyInstance(classLoader, new Class[]{IUserDao.class}, proxy);
        userDaoProxy.save();
    }
}

输出结果:

开始事务
保存用户
提交事务

在JDK动态代理实现中,代理类的核心逻辑在invoke()方法实现中,其中第一个参数是代理类的实例、第二个参数是正在被调用的接口方法、第三个参数是被调用接口方法的参数。在invoke()方法中,我们可以调用被代理对象的相关方法,并在方法调用前后进行增强处理。

除了JDK动态代理,还有一些其他代理框架如:CGLIB、Javassist等,它们的实现原理与JDK动态代理并不一样,但是它们都可以实现动态代理的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Java动态代理与静态代理 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 开源多线程性能测试工具-sysbench

    开源多线程性能测试工具-sysbench Sysbench是一个开源的跨平台多线程性能测试工具,可以用来测试数据库、计算机系统、文件系统等各种应用的性能。它可以仿真出不同的测试负载并向系统施压,以此来测量系统的性能表现和稳定性,同时可以发现系统的瓶颈。 Sysbench可以对CPU、内存、文件IO、调度系统、数据库等进行各种性能测试。它通过多个测试模块模拟负…

    其他 2023年3月28日
    00
  • SpringBoot如何使用applicationContext.xml配置文件

    SpringBoot提供了一种更简单、更快速的方式来开发基于Spring框架的应用程序。在使用SpringBoot时,若需要使用applicationContext.xml配置文件,则需要进行以下步骤: 在SpringBoot项目中创建resources文件夹。 在resources文件夹中创建applicationContext.xml文件。 在appli…

    other 2023年6月25日
    00
  • 利用PHP和百度ai实现文本以及图片的审核

    下面是关于利用PHP和百度AI实现文本以及图片的审核的完整攻略,包括百度AI的使用方法、PHP代码实现、以及两个示例说明。 百度AI的使用方法 百度AI提供了文本审核和图片审核两种服务,可以通过API接口进行调用。在使用之前,需要先注册百度AI账号,并创建应用,获取API Key和Secret Key。 文本审核 文本审核可以检测文本中的敏感词、色情词、暴恐…

    other 2023年5月6日
    00
  • Win10专业版错误提示“你的电脑遇到问题,需要重新启动”怎么办

    Win10专业版错误提示“你的电脑遇到问题,需要重新启动”怎么办? 概述 在使用 Windows 10 专业版计算机时,有时可能会遇到错误提示“你的电脑遇到问题,需要重新启动”。这种错误通常被称为 BSOD 或蓝屏(Blue Screen of Death),并且可能由多种原因引起。 本文将提供一些可能有助于解决此问题的步骤和建议。 步骤 步骤1:等待重启完…

    other 2023年6月27日
    00
  • thinkPHP模型初始化实例分析

    当我们在ThinkPHP中进行数据库操作时,通常需要定义一个模型来进行数据库的操作。在模型进行操作之前,需要初始化一个包含数据库配置等基础信息的实例。本文将会详细讲解ThinkPHP模型初始化实例的构建方式,方便开发者在进行数据库操作时更加容易上手。 第一步:创建模型 在使用ThinkPHP模型进行数据库操作前,需要先创建一个模型。可以通过命令行工具或者手动…

    other 2023年6月20日
    00
  • Java 爬虫数据异步加载如何解决

    Java爬虫在处理数据时,如果遇到异步加载的情况,可能会导致数据获取不完整或者获取失败的问题。下面我将详细讲解Java爬虫如何解决异步加载数据的问题。 1. 了解网页异步加载的原理 网页异步加载是指在页面加载完成之后,通过JavaScript等技术异步向服务器请求数据,来达到实时更新页面内容的效果。这种异步加载的方式可以大大提高用户体验,但对于爬虫的数据获取…

    other 2023年6月25日
    00
  • 一起学vue:crud(增删改查)

    一起学 Vue:CRUD(增删改查) 在 web 开发中,CRUD 是最基础的操作之一,它即增加、查询、更新和删除(Create, Read, Update 和 Delete)数据操作。本文将带领大家学习 Vue.js 如何实现 CRUD 操作。 前置知识 在开始学习 Vue.js 中 CRUD 的实现,需要先掌握 Vue.js 基础知识,具体包括: Vue…

    其他 2023年3月29日
    00
  • C++运算符重载三种形式(成员函数,友元函数,普通函数)详解

    C++运算符重载三种形式详解 在C++中,运算符重载是一种非常强大的机制,可以根据不同的需求重载各种运算符。在运算符重载中,常见的有成员函数、友元函数和普通函数三种形式,本文将详细介绍这三种形式的使用方法和注意事项。 成员函数形式 成员函数形式是在类内部定义的一个成员函数,其函数名以运算符关键字开头,在函数定义中并没有指定访问级别。当运算符作用于类的对象时,…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部