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

yizhihongxing

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日

相关文章

  • 几种常用DB驱动和DB连接串小结

    关于“几种常用DB驱动和DB连接串小结”的攻略,以下是详细的介绍和示例说明。 1. 常见的DB驱动 在Java中常用的DB驱动主要有以下几种: 1.1 MySQL驱动 MySQL驱动目前最常用的是Connector/J,它是MySQL官方提供的Java驱动程序。可以从MySQL官网下载到最新的MySQL驱动。 1.2 Oracle驱动 Oracle官方提供的…

    Java 2023年6月16日
    00
  • spring boot实战之本地jar包引用示例

    下面就为大家详细讲解 “spring boot实战之本地jar包引用示例”的完整攻略。 1. 前置知识 在介绍本地Jar包引用之前,我们需要先掌握以下基础知识: Java的classpath概念,即classpath的含义与用法 Maven的本地仓库,即本地仓库的含义与配置 Maven的工作原理,即pom.xml文件的作用 2. 引用本地Jar包示例 2.1…

    Java 2023年5月20日
    00
  • 用简单的代码来实现文件上传

    让我来详细讲解一下“用简单的代码来实现文件上传”的完整攻略。 什么是文件上传? 在网站开发中,文件上传就是指用户将本地的文件通过网站上传到服务器中。 实现文件上传的原理 实现文件上传,需要配合HTTP协议,主要分为以下几步: 用户通过网页上传文件,前端通过HTML5的FormData对象将文件数据以二进制流的形式传递到后端。 后端接收到上传的文件数据后,将文…

    Java 2023年6月15日
    00
  • 用Maven打成可执行jar,包含maven依赖,本地依赖的操作

    Maven 是一个强大的项目管理工具,可以帮助开发者自动下载和安装项目所需的依赖,并且可以将项目打包成可执行的 jar 文件。下面是用 Maven 将项目打包成可执行的 jar,同时包含 Maven 依赖和本地依赖的操作攻略。 1. 在 pom.xml 文件中配置插件 在 Maven 的 pom.xml 文件中,可以通过配置插件的方式来打包成可执行的 jar…

    Java 2023年5月20日
    00
  • java线程池实现批量下载文件

    关于Java线程池实现批量下载文件,可以按照以下步骤进行: 1. 创建线程池 首先需要使用 Executors.newFixedThreadPool() 方法创建一个固定大小的线程池,例如: private static int THREAD_COUNT = 5; // 线程池大小 private static ExecutorService executo…

    Java 2023年5月19日
    00
  • java实现在线聊天系统

    Java实现在线聊天系统攻略 在线聊天系统是一种常见的即时通讯方式,Java是一种广泛使用的编程语言,因此Java实现在线聊天系统是一个非常有意义的项目。本文将介绍如何实现Java在线聊天系统。 第一步:确定技术栈 实现在线聊天系统需要以下技术栈: Java编程语言 Spring Boot框架 WebSocket通信协议 Thymeleaf模板引擎 MySQ…

    Java 2023年5月19日
    00
  • Mybatis批量更新三种方式的实现

    首先我们可以从三种方式的实现入手进行讲解。 方式一:使用foreach标签 使用foreach标签是MyBatis中批量更新的最常用也是最简单的方式。通过foreach标签,可以将多个更新操作一次性提交到数据库中,实现批量更新的效果。 具体实现步骤如下: 在mapper配置文件中定义批量更新的SQL语句,语句中要使用到foreach标签。 <updat…

    Java 2023年5月20日
    00
  • JSP代码实现 金字塔(倒置)示例

    下面我将为你详细讲解“JSP代码实现金字塔(倒置)示例”的完整攻略。 1. 编写 JSP 页面 我们首先需要编写一个 JSP 页面来实现金字塔倒置的功能。在 JSP 页面中,我们需要使用嵌入式 Java 代码来实现金字塔倒置的逻辑。以下是一个示例的 JSP 页面: <%@ page language="java" contentTy…

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