Spring中AOP概念与两种动态代理模式原理详解

Spring中AOP概念与两种动态代理模式原理详解

什么是AOP

AOP(Aspect Oriented Programming),面向切面编程,是OOP(Object Oriented Programming)的一个补充,它利用一种称为"切面(Aspect)"的技术,将一些与业务无关,却为业务模块所共同调用的功能,如日志记录、性能统计、安全控制、事务处理等,封装成"切面",并将其对应的代码尽可能地去耦合,从而改进了程序的结构。

AOP 的实现,在Java 中有两种方式,一种是静态代理,一种是动态代理。在Spring框架中,默认使用的是动态代理。

静态代理

代理类的实现

静态代理,是通过编写代理类的方式来实现。代理类与目标类共同实现一个共同的接口或者继承一个共同的抽象类,使得代理类可以对目标类进行功能增强。下面示例代码:

// 被代理对象
public interface Calculator {
    int add(int a, int b);
}

// 目标对象
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}

// 代理对象
public class CalculatorProxy implements Calculator {
    private Calculator calculator;

    public CalculatorProxy(Calculator calculator) {
        this.calculator = calculator;
    }

    @Override
    public int add(int a, int b) {
        System.out.println("静态代理:before add");
        int result = calculator.add(a, b);
        System.out.println("静态代理:after add");
        return result;
    }
}

静态代理的使用

下面是对静态代理的使用示例代码:

Calculator calculator = new CalculatorImpl();
CalculatorProxy calculatorProxy = new CalculatorProxy(calculator);
int result = calculatorProxy.add(1, 2);
System.out.println("result = " + result);

动态代理

代理类的实现

动态代理是在运行时通过创建一个代理类的对象来间接创建目标对象,动态代理有两种实现方式:一个是Java 自带的动态代理,另一个是CGLib动态代理。

Java 动态代理

Java动态代理是利用反射机制,在运行时动态生成一个代理类,这个代理类就实现了目标对象的接口,从而可以调用目标对象的方法,并在调用前后实现自己的方法增强。

下面是一个实现InvocationHandler接口的代理类的示例代码:

public class CalculatorInvocationHandler implements InvocationHandler {
    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Java动态代理:before " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("Java动态代理:after " + method.getName());
        return result;
    }
}

CGLib 动态代理

CGLib代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。所以,CGLib代理对象要求类不能被final关键字所修饰。

下面是一个实现MethodInterceptor接口的代理类的示例代码:

public class CalculatorMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("CGLib动态代理:before " + method.getName());
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("CGLib动态代理:after " + method.getName());
        return result;
    }
}

动态代理的使用

下面是对Java动态代理的使用示例代码:

Calculator calculator = new CalculatorImpl();
CalculatorInvocationHandler calculatorInvocationHandler = new CalculatorInvocationHandler(calculator);
Calculator proxy = (Calculator) Proxy.newProxyInstance(calc.getClass().getClassLoader(), calc.getClass().getInterfaces(), calculatorInvocationHandler);
int result = proxy.add(1, 2);
System.out.println("result = " + result);

下面是对CGLib动态代理的使用示例代码:

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(CalculatorImpl.class);
enhancer.setCallback(new CalculatorMethodInterceptor());
CalculatorImpl calculatorProxy = (CalculatorImpl) enhancer.create();
int result = calculatorProxy.add(1, 2);
System.out.println("result = " + result);

总结

本文介绍了Spring中AOP概念与两种动态代理模式原理详解,包括静态代理、Java动态代理和CGLib动态代理。静态代理是通过编写代理类的方式来实现,而动态代理是在运行时通过创建一个代理类的对象来间接创建目标对象,而动态代理有两种实现方式。在Spring框架中,默认使用的是动态代理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring中AOP概念与两种动态代理模式原理详解 - Python技术站

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

相关文章

  • Sprint Boot @DeleteMapping使用方法详解

    @DeleteMapping是Spring Boot中的一个注解,它用于将HTTP DELETE请求映射到控制器方法上。在使用Spring Boot开发Web应用程序时,@DeleteMapping是非常重要的。本文将详细介绍@DeleteMapping的作用和使用方法,并提供两个示例说明。 @DeleteMapping的作用 @DeleteMapping的…

    Java 2023年5月5日
    00
  • Java详细讲解文件的读写操作方法

    Java详细讲解文件的读写操作方法 文件读取操作 在Java中,可以使用FileInputStream和BufferedInputStream,以及Reader类中的FileReader和BufferedReader类来读取文件。下面是一个读取TXT文件的示例代码: import java.io.*; public class FileReadDemo { …

    Java 2023年5月20日
    00
  • Java ArrayList实现班级信息管理系统

    下面我来详细讲解一下“Java ArrayList实现班级信息管理系统”的完整攻略,包括以下内容: 1. 环境准备 首先需要安装Java开发环境,建议使用JDK 8或更高版本。可以到Oracle官网下载安装。 2. 创建班级类 创建一个班级类,可以定义班级名称、班主任姓名、学生列表等属性和方法。一个简单的班级类的示例代码如下: public class Cl…

    Java 2023年5月24日
    00
  • java9新特性Reactive Stream响应式编程 API

    Java 9 增加了 Reactive Stream 响应式编程 API,使得开发者能够更方便地实现响应式编程。本文将详细解释 Reactive Stream API 的用法,并提供示例代码来说明。 Reactive Stream 简介 Reactive Stream 是一种用于异步编程的编程模型,它能够处理大数据流和异步操作。Reactive Stream…

    Java 2023年5月26日
    00
  • 深入jaxb xjc编码问题的详细介绍

    下面我来详细讲解“深入JAXB XJC编码问题的详细介绍”的攻略。 什么是JAXB XJC? JAXB(Java Architecture for XML Binding)是Java中一个处理XML编码和解码的框架。JAXB XJC是JAXB中用于将XSD(XML Schema Definition)文件转换为Java类的工具。它可以生成一组Java类,包括…

    Java 2023年5月20日
    00
  • java LeetCode普通字符串模拟题解示例

    Java LeetCode普通字符串模拟题解示例攻略 1. 题目简述 本题是一道字符串模拟题目,要求实现一个String模拟类,具有以下功能: 初始化操作:构造函数接受一个字符串作为参数,将其存储在对象中。 获取字符串操作:实现一个charAt方法,接受一个整数索引index,返回字符串指定位置的字符;实现一个substring方法,接受两个整数索引star…

    Java 2023年5月19日
    00
  • java实现哈夫曼压缩与解压缩的方法

    Java实现哈夫曼压缩与解压缩的方法 哈夫曼编码是一种有效的无损压缩算法,常用于压缩文本文件等数据。本文将详细介绍如何使用Java实现哈夫曼压缩与解压缩的方法。 哈夫曼压缩 1. 构建哈夫曼树 首先需要构建一个哈夫曼树,该树的每个叶子节点都代表一个字符,并且每个叶子节点的编码都是唯一的。构建哈夫曼树的过程如下: 统计给定文本中每个字符出现的频率。 将字符频率…

    Java 2023年5月20日
    00
  • 【Jmeter】按比例分配Api压测

    先看 【Jmeter】基础介绍-详细 【Jmeter】Request1输出作为Request2输入-后置处理器 继续聊提出的第二个问题,即   2.需要按比例分配API请求并发,以模拟真实的API压力场景 做压测的时候,一般的需求都是多个API同时压,不然也看不出真正的tps是多少啊。 比如虽然接口a的需求并发不高,500个用户才请求一次,但是特别耗性能,导…

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