Java JDK动态代理(AOP)用法及实现原理详解

Java JDK动态代理(AOP)用法及实现原理详解

1. 什么是动态代理(AOP)?

动态代理是一种代理设计模式中的一种实现方式。一般的代理模式需要我们手动编写代理对象来实现代理,但是动态代理允许我们在运行时动态的创建代理对象,这样就无需手动编写代理对象了。常常使用动态代理实现切面编程(AOP)。

2. Java JDK动态代理实现原理

动态代理是基于Java反射机制实现的。Java JDK中提供了两个类:java.lang.reflect.InvocationHandler负责调用处理器的接口和java.lang.reflect.Proxy用来生成代理对象。 JDK动态代理的实现原理主要分成以下三个步骤:

  1. 创建InvocationHandler接口的实现类(调用处理器类),并实现invoke()方法,该方法是动态代理的核心,用于聚拢目标方法和增强代码,并返回结果。
  2. 获取类的ClassLoader和所有接口interfaces。
  3. 通过Proxy.newProxyInstance()方法创建代理实例。

3. Java JDK动态代理示例1

实现一个动态代理类,当调用目标方法时,打印方法名和参数,并在方法执行前后加上增强代码。

public interface UserService {
    void save(String name);
}

public class UserServiceImpl implements UserService {
    @Override
    public void save(String name) {
        System.out.println("save user: " + name);
    }
}

public class UserInvocationHandler implements InvocationHandler {
    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("准备执行 " + method.getName() + " 方法,参数为 " + Arrays.toString(args));
        Object result = method.invoke(target, args);
        System.out.println(method.getName() + " 方法执行完毕,返回结果: " + result);
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        InvocationHandler invocationHandler = new UserInvocationHandler(userService);
        UserService proxy = (UserService) Proxy.newProxyInstance(
                userService.getClass().getClassLoader(),
                userService.getClass().getInterfaces(),
                invocationHandler);
        proxy.save("张三");
    }
}

4. Java JDK动态代理示例2

使用动态代理实现AOP,假设有一个学生类Student,它的某个方法study(),我们要在调用study()方法前后打印日志,示例代码如下:

public interface Student {
    void study(String course);
}

public class StudentImpl implements Student {
    @Override
    public void study(String course) {
        System.out.println("学生正在学习 " + course);
    }
}

public class StudentLog {
    public void beforeStudy() {
        System.out.println("准备学习,开始记录日志");
    }

    public void afterStudy() {
        System.out.println("学习完毕,结束记录日志");
    }
}

public class StudentInvocationHandler implements InvocationHandler {
    private Object target;
    private Object aspect;

    public StudentInvocationHandler(Object target, Object aspect) {
        this.target = target;
        this.aspect = aspect;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Method beforeMethod = aspect.getClass().getMethod("beforeStudy");
        Method afterMethod = aspect.getClass().getMethod("afterStudy");
        beforeMethod.invoke(aspect);
        Object result = method.invoke(target, args);
        afterMethod.invoke(aspect);
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Student student = new StudentImpl();
        StudentLog studentLog = new StudentLog();
        StudentInvocationHandler handler = new StudentInvocationHandler(student, studentLog);

        Student proxy = (Student) Proxy.newProxyInstance(
                student.getClass().getClassLoader(),
                student.getClass().getInterfaces(),
                handler);

        proxy.study("数学");
    }
}

5. 总结

以上,就是Java JDK动态代理(AOP)用法及实现原理详解的完整攻略。动态代理具有很强的灵活性和通用性,可以节约大量代码和维护代理对象的时间。使用动态代理方式进行AOP编程能够很好地解决大量重复代码和模板代码的问题,使得程序变得更加清晰和简洁。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java JDK动态代理(AOP)用法及实现原理详解 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • Spring BPP中如何优雅的创建动态代理Bean详解

    为了讲解“Spring BPP中如何优雅的创建动态代理Bean”,我们首先需要了解BPP是什么。BPP(BeanPostProcessor)是Spring IoC容器提供的扩展机制,可以在Bean的实例化过程中,对Bean进行增强、修改和替换等操作。而动态代理则是Spring AOP中常用的技术,能够实现切面编程的目的。 在Spring中,我们可以使用BPP…

    Java 2023年5月20日
    00
  • 在CentOS 6.3中安装与配置Tomcat-7方法

    以下是“在CentOS 6.3中安装与配置Tomcat-7方法”的完整攻略: 安装Java 首先,从官网下载Java安装包。在本示例中,我们将操作JDK 8版本: wget –no-check-certificate –no-cookies –header "Cookie: oraclelicense=accept-securebackup-…

    Java 2023年5月19日
    00
  • 详细总结Java创建文件夹的方法及优缺点

    详细总结Java创建文件夹的方法及优缺点 在Java中,创建文件夹是一个常见的操作,无论是在后端开发还是在桌面应用程序中都很常用。本文将详细总结Java创建文件夹的方法及优缺点,包括三种方法。 方法一:使用File类的mkdir() File类是Java中的一个常用文件操作类,其中的mkdir()方法可以用于创建一个新的文件夹。 File file = ne…

    Java 2023年5月20日
    00
  • 微信小程序实现上传图片功能

    为了能更好地讲解实现上传图片功能的攻略,我会先介绍一下常用的两种上传方式,再分别对其进行示例说明,最后提供具体的代码实现。 常见的图片上传方式 表单上传 表单上传是指通过表单提交的方式将图片上传至服务器,传统的网页上传图片一般采用表单上传的方式。文件上传需要使用input元素, 其中type属性设为file。在提交表单时,浏览器会把文件的二进制数据打包成 M…

    Java 2023年5月23日
    00
  • SSM框架整合之Spring+SpringMVC+MyBatis实践步骤

    SSM框架整合之Spring+SpringMVC+MyBatis实践步骤 SSM框架整合是Java Web开发中常用的一种方式,它将Spring、SpringMVC和MyBatis三个框架整合在一起,可以提高开发效率和代码质量。本文将详细介绍SSM框架整合的实践步骤,并提供两个示例说明。 实践步骤 步骤一:创建Maven项目 首先,我们需要创建一个Maven…

    Java 2023年5月17日
    00
  • java实现翻转单词顺序列

    以下是Java实现翻转单词顺序列的完整攻略。 题目描述 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。例如,“I am a student.”,翻转成“student. a am I”。 思路分析 可以将输入的句子按照空格进行分割,得到各个单词,然后按照倒序进行拼接得到翻转后的句子。需要注意的是,如果句子中有多个连续的空格,需要进行处理。 …

    Java 2023年5月27日
    00
  • java实现饭店点菜系统

    实现饭店点菜系统主要包含以下步骤: 设计数据库 第一步是设计数据库。我们可以使用MySQL等关系型数据库,设计需要至少两个表:一个存储菜品信息,一个存储订单信息。其中,菜品信息表需要包含菜品名称、菜品种类、价格、描述等字段;订单信息表需要包含订单编号、顾客姓名、联系方式、订单状态、订单总价等字段。 编写后端API 第二步是编写后端API(Applicatio…

    Java 2023年5月18日
    00
  • Java 替换字符串中的回车换行符的方法

    Java 替换字符串中的回车换行符的方法可以通过使用正则表达式来实现。以下是完整的示例攻略: 方法一:使用 replaceAll() 方法 可以使用 replaceAll() 方法将字符串中的回车换行符替换为其他内容。需要使用正则表达式 “\r|\n” 匹配回车换行符,并使用 replaceAll() 方法将其替换为需要的内容。具体示例代码如下: Strin…

    Java 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部