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日

相关文章

  • SpringBoot 使用 FTP 操作文件的过程(删除、上传、下载文件)

    一、引言 在生产环境中,经常会使用FTP(文件传输协议)来上传和下载文件。本文将会详细地讲解如何在Spring Boot应用中使用FTP操作文件,包括文件的上传、下载、删除等操作。 二、FTP操作文件的依赖 在使用Java操作FTP的过程中,需要引入两个依赖: <!– FTP客户端依赖 –> <dependency> <gr…

    Java 2023年5月20日
    00
  • 详解MybatisPlus集成nacos导致druid连接不上数据库

    我很高兴为您提供“详解MybatisPlus集成nacos导致druid连接不上数据库”的完整攻略。 问题描述MybatisPlus集成nacos后,我们发现druid连接池无法连接数据库了,导致应用程序无法启动。这是由于Druid数据源在生成时需要使用一些配置参数,例如驱动类名、连接字符串、用户名/密码等,而这些参数在nacos配置中心中没有被正确指定。 …

    Java 2023年6月15日
    00
  • Java实现排球比赛计分系统

    Java实现排球比赛计分系统 概述 排球是一项很受欢迎的运动项目,计分是比赛中必不可少的环节。本文将介绍如何使用 Java 实现排球比赛计分系统。 实现思路 排球比赛分为五局制,每局比赛先得分 25 分,并且要领先对手 2 分以上。如果进入决胜局(第五局),则比赛先得分 15 分,同样需要领先对手 2 分以上。 在进行比赛时,我们需要记录两个队伍的分数,以及…

    Java 2023年5月24日
    00
  • 解析Linux下Varnish缓存的配置优化

    解析Linux下Varnish缓存的配置优化 Varnish是一款高性能的Web缓存程序,它能够在内存中存储分别从Web服务器和客户端接受到的HTTP数据。本文将教你如何通过在Linux下配置和优化Varnish缓存来提高网站的性能。 安装Varnish Varnish可在多个Linux发行版上运行,以下是在Ubuntu 18.04上安装Varnish的方法…

    Java 2023年6月15日
    00
  • java中response对象用法实例分析

    Java中Response对象用法实例分析 在Java的Web开发中,Response对象是常用的一个对象。它用于向客户端发送响应信息,同时还可以设置Cookie、Header等信息。本文将介绍Java中Response对象的用法,包括常见的方法和示例说明。 Response对象常用方法 1. 设置响应头信息 使用Response对象的setHeader()…

    Java 2023年5月26日
    00
  • 使用Spring方法拦截器MethodInterceptor

    使用Spring方法拦截器MethodInterceptor可以在方法执行前、执行后、抛出异常时等时刻进行自定义的操作。以下是完整攻略及两条示例: 1. 导入Spring AOP依赖 在项目的pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework</groupId&…

    Java 2023年5月19日
    00
  • spring boot 日志配置详解

    Spring Boot是一个快速开发框架,可以帮助开发人员快速构建Web应用程序。在开发过程中,日志记录是非常重要的,可以帮助开发人员快速定位和解决问题。本文将介绍Spring Boot的日志配置详解,并提供两个示例。 Spring Boot的日志配置 Spring Boot的日志配置非常灵活,可以根据需要进行配置。在默认情况下,Spring Boot使用L…

    Java 2023年5月15日
    00
  • Springboot整合策略模式详解

    Spring Boot整合策略模式详解 策略模式是一种常用的设计模式,它可以帮助我们在运行时选择不同的算法或行为。在本文中,我们将详细讲解如何在Spring Boot中使用策略模式,并提供两个示例来演示如何使用策略模式。 策略模式简介 策略模式是一种行为型设计模式,它定义了一系列算法或行为,并将它们封装在独立的类中,使得它们可以相互替换。策略模式可以帮助我们…

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