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日

相关文章

  • 利用Java计算某个日期是星期几

    计算某个日期是星期几可以使用Java自带的Calendar类来实现。下面是一些示例代码,演示如何获取某个日期对应的星期。 示例一:获取当前日期所对应的星期 import java.util.Calendar; public class DateOfWeek { public static void main(String[] args) { Calendar…

    Java 2023年5月20日
    00
  • 面试阿里,腾讯90%会被问到的25个问题(附答案)

    下面是详细讲解“面试阿里,腾讯90%会被问到的25个问题(附答案)”的完整攻略。 1. 了解自己 这道问题是面试中常见的开场白,通过这个问题,面试官可以了解你的背景和经历,进一步了解你的职业规划。针对这个问题,你需要从以下几个方面说明: 个人背景:学历、专业、工作年限等。 工作经历:所在公司、职位、工作职责,取得的成绩和荣誉。 个人特点:自我评价,成就和不足…

    Java 2023年5月26日
    00
  • Java Apache Commons报错“UnhandledException”的原因与解决方法

    “UnhandledException”是Java的ApacheCommons类库中的一个异常,通常由以下原因之一引起: 代码错误:如果代码中存在错误,则可能会出现此异常。例如,可能会使用错误的方法或参数。 系统错误:如果系统中存在错误,则可能会出现此异常。例如,可能会出现内存不足或文件系统错误。 以下是两个实例: 例1 如果代码中存在错误,则可以尝试检查代…

    Java 2023年5月5日
    00
  • Java 操作Properties配置文件详解

    Java操作Properties配置文件详解 在Java开发中,Properties是一种经常使用的配置文件格式。Properties文件是一种键值对的格式,它通常用来存储应用程序的配置信息,比如数据库的连接信息、系统参数等等。 Properties的基本格式 Properties文件通常是一个以.properties为后缀的文本文件,其中每一行都是一个键值…

    Java 2023年5月20日
    00
  • Spring Security权限管理实现接口动态权限控制

    以下是关于Spring Security权限管理实现接口动态权限控制的完整攻略: 1. 什么是接口动态权限控制 接口动态权限控制即根据用户的权限动态的对接口进行权限控制,这个过程可以分为两步:一是获取用户所拥有的权限,二是根据用户所拥有的权限动态的对接口进行控制。 2. Spring Security实现接口动态权限控制的步骤 以下是实现Spring Sec…

    Java 2023年6月3日
    00
  • Springboot使用influxDB时序数据库的实现

    接下来我将详细讲解“Springboot使用influxDB时序数据库的实现”的完整攻略。首先需要明确的是,influxDB是一个高性能的时序数据库,专门用于处理时间序列数据。而Springboot是一个基于Spring框架的应用程序快速开发框架。 引入influxDB依赖 在Springboot项目的pom.xml文件中,添加以下依赖: <depen…

    Java 2023年5月20日
    00
  • Java多线程编程小实例模拟停车场系统

    Java多线程编程小实例模拟停车场系统攻略 概述 本实例主要使用Java多线程编程,模拟停车场系统,包括车辆入场、出场、停车等基本功能。该系统采用面向对象思想,通过多线程程序的编写,模拟实现停车场系统的相关功能。 实现步骤 设计车辆类 首先要设计车辆类,包括车牌号、车型、停车时间、出场时间等属性。以下是车辆类的示例代码: class Car { privat…

    Java 2023年5月19日
    00
  • SpringBoot集成quartz实现定时任务详解

    SpringBoot集成Quartz实现定时任务详解 1. 什么是Quartz Quartz是一个开源的作业调度框架,其主要用于定时调度任务。它能够完成复杂的调度需求,如在指定时间执行任务、每天执行任务、周末执行任务等。 2. SpringBoot集成Quartz 2.1 引入依赖 我们首先需要在pom.xml文件中引入quartz和spring-boot-…

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