【Spring进阶】基于注解的面向切面编程(AOP)详解

hi,我是程序员王也,一个资深Java开发工程师,平时十分热衷于技术副业变现和各种搞钱项目的程序员~,如果你也是,可以一起交流交流。

今天我们聊一聊Spring中的AOP~

在这里插入图片描述


AOP的核心概念

面向切面编程(AOP)是一种编程范式,它允许开发者将横切关注点(如日志记录、事务管理、安全性等)与业务逻辑分离,从而提高代码的模块化和可维护性。在Java中,AOP通常通过使用框架如Spring来实现。

  1. 介绍AOP的关键术语

    • 切面(Aspect):切面是封装横切关注点的模块。它包含了一组通知(Advice)和切入点(Pointcut)。
    • 连接点(Joinpoint):在程序执行过程中的特定点,如方法的调用或执行,异常的抛出等。
    • 切点(Pointcut):切点是定义在哪些连接点上应用通知的规则。
    • 通知(Advice):通知是在切点上执行的代码,它定义了在连接点上执行的逻辑,如前置、后置、环绕等。
  2. 解释AOP的几种通知类型

    • 前置(Before):在方法执行前执行的通知。
    • 后置(After):在方法执行后执行的通知,无论方法是否成功执行。
    • 环绕(Around):在方法调用前后都可以执行的通知,可以控制方法的调用过程。
    • 异常(Throws):在方法抛出异常后执行的通知。
    • 最终(AfterReturning):在方法正常返回后执行的通知。

案例源码说明

以下是一个简单的Spring AOP示例,展示了如何使用前置通知:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void beforeAdvice(JoinPoint joinPoint) {// 这里可以获取到连接点的信息,如方法名、参数等String methodName = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("Before advice: " + methodName + " with args " + Arrays.toString(args));}
}

Spring框架中的AOP实现

Spring框架是一个全面的Java EE企业应用开发框架,它提供了对AOP的强大支持。Spring AOP使得开发者能够以声明式的方式将横切关注点与业务逻辑分离。

  1. 介绍Spring AOP的基本概念和功能

    Spring AOP基于代理机制,它允许你在不修改目标对象的情况下,通过代理对象对目标对象进行扩展。Spring AOP主要支持方法的前置、后置、环绕、异常和最终通知。

  2. 讨论Spring AOP与AspectJ的关系和差异

    Spring AOP和AspectJ都是面向切面编程的技术,但它们有不同的应用场景和特点。Spring AOP更适合于企业应用中的声明式事务管理等场景,而AspectJ提供了更强大的切面编程能力,适用于更复杂的AOP场景。

  3. 展示如何使用Spring配置AOP

    以下是一个Spring配置AOP的示例:

    <!-- 开启Spring AOP支持 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/><!-- 定义切面 -->
    <bean id="loggingAspect" class="com.example.LoggingAspect"/><!-- 配置切入点 -->
    <aop:config><aop:pointcut id="serviceMethods" expression="execution(* com.example.service.*.*(..))"/><aop:aspect ref="loggingAspect"><aop:before pointcut-ref="serviceMethods" method="beforeAdvice"/></aop:aspect>
    </aop:config>
    

    在这个Spring XML配置示例中,我们首先开启了AOP支持,并指定了代理的目标类。然后,我们定义了一个loggingAspect切面,并配置了一个切入点serviceMethods。最后,我们将这个切入点与切面的beforeAdvice方法关联起来。

案例源码说明

以下是一个使用注解配置Spring AOP的示例:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void beforeAdvice(JoinPoint joinPoint) {// 记录日志System.out.println("Before advice executed");}
}

在这个例子中,我们使用注解@Aspect@Component定义了一个切面组件LoggingAspect。我们使用@Before注解来声明一个前置通知,它将在使用Spring AOP时自动应用到匹配指定切入点表达式的方法上。


基于注解的AOP配置

在Spring框架中,除了使用XML配置AOP外,还可以通过注解来实现AOP的配置。使用注解可以减少配置的复杂性,使代码更加简洁。

  1. 介绍Spring中基于注解的AOP配置方法

    基于注解的AOP配置主要涉及以下几个注解:

    • @Aspect:用于声明一个类为切面。
    • @Component:将切面类作为Spring管理的组件。
    • @Before@After@Around@AfterThrowing@AfterReturning:用于定义不同类型的通知。
  2. 展示如何使用@Aspect注解定义切面

    以下是一个使用@Aspect注解定义切面的示例:

    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;@Aspect
    @Component
    public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void beforeAdvice(JoinPoint joinPoint) {// 执行前置逻辑System.out.println("Before advice executed on method: " + joinPoint.getSignature().getName());}
    }
    

    在这个例子中,LoggingAspect类被声明为一个切面,并且使用了@Before注解来定义一个前置通知。这个通知将在执行匹配指定切入点表达式的任何方法之前执行。

  3. 展示如何使用@Before、@After、@Around、@AfterThrowing和@AfterReturning注解定义通知

    以下是使用不同类型通知注解的示例:

    @After("execution(* com.example.service.*.*(..))")
    public void afterAdvice(JoinPoint joinPoint) {// 执行后置逻辑
    }@Around("execution(* com.example.service.*.*(..))")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {// 执行环绕逻辑Object result = proceedingJoinPoint.proceed();return result;
    }@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "error")
    public void afterThrowingAdvice(JoinPoint joinPoint, Throwable error) {// 执行异常通知逻辑
    }@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {// 执行返回通知逻辑
    }
    

AOP的高级特性

AOP(面向切面编程)的高级特性包括对切入点表达式的灵活使用,以及在复杂的应用场景中应用AOP,如性能监控、日志记录、事务管理等。

  1. 介绍切入点表达式(pointcut expressions)

    切入点表达式是Spring AOP中用于定义哪些连接点将被增强的表达式。Spring AOP支持多种切入点表达式,包括:

    • execution:基于方法的执行进行匹配,如execution(* com.example.service.*.*(..))
    • within:基于类的结构进行匹配,如within(com.example.service.*)
    • this:匹配特定类型的代理对象,如this(com.example.Auditable)
    • target:匹配目标对象的类型,如target(com.example.Auditable)
    • args:匹配方法参数的类型,如args(java.lang.String)
  2. 正则表达式在AOP中的应用

    在Spring AOP中,可以使用正则表达式来定义切入点表达式,这提供了一种灵活的方式来匹配复杂的类名或方法名模式。

    案例源码说明

    @Aspect
    @Component
    public class PerformanceMonitoringAspect {@Before("execution(* com.example.service.*.*(..)) && args(..)")public void recordPerformanceMetrics(JoinPoint joinPoint) {// 记录方法调用前的时间戳long startTime = System.currentTimeMillis();// 执行方法// ...// 记录方法调用后的时间戳long endTime = System.currentTimeMillis();// 计算执行时间long executionTime = endTime - startTime;// 记录性能指标System.out.println("Performance metrics for " + joinPoint.getSignature().getName() + ": " + executionTime + " ms");}
    }
    

    在这个例子中,我们定义了一个用于性能监控的切面,它将在执行匹配指定切入点表达式的方法之前记录性能指标。

  3. 讨论使用AOP进行性能监控、日志记录、事务管理等高级应用场景

    AOP可以用于实现许多高级应用场景,例如:

    • 性能监控:在服务层方法前后记录性能指标,以监控应用的性能瓶颈。
    • 日志记录:在关键业务方法前后添加日志记录,以跟踪业务流程和调试问题。
    • 事务管理:使用AOP来声明性地管理事务,确保事务的一致性和隔离性。
    • 安全性控制:在方法执行前后检查权限,以实现安全性控制。

总结

AOP的高级特性使得开发者能够以声明式的方式处理复杂的应用场景。通过灵活使用切入点表达式和正则表达式,可以在Spring AOP中实现精确的连接点匹配。此外,AOP在性能监控、日志记录、事务管理等场景中的应用,展示了其在提高代码模块化和可维护性方面的强大能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【一】ECharts----【基本概念、基本实例】

目录 零.前言 一.ECharts的安装 1.1独立版本的安装 1.2CDN的安装 1.3NPM的安装 二.ECharts实例 三.系列(series) 四.创建一个ECharts图表的基本步骤 4.1创建一个DOM容器 4.2使用DOM节点初始化ECharts对象 4.3设置配置信息 4.3.1图表标题 4.3.2提示信息 4.3.3图例组…

提取点云-------PCL

提取点云 /// <summary> /// VoxelGrid滤波下采样 /// </summary> /// <param name"cloud">需要滤波的点云</param> /// <param name"lx">三维体素栅格的x</param> /// <param name"ly">三维体素栅格…

全新Linux教程-驱动大全-PCI和PCIe子系统-P2-PCI设备的访问方法-非桥设备

主要讲PCI设备的硬件访问方法。 1、PCI的硬件结构 CPU发出的地址是CPU地址&#xff0c;可能是访问底下任何一个设备。地址范围不一样&#xff0c;访问到的外设就不一样。在嵌入式中&#xff0c;通常将4G内存地址空间分成好几个区域&#xff0c;不同的访问分给不同的地址。桥内…

Github首页美化(updating)

Github首页美化 一、新建仓库二、美化Github首页主页访问量统计仓库状态统计常用语言占比统计社交链接 界面展示 一、新建仓库 对Github首页进行美化&#xff0c;需要新建一个仓库名和自己 Github 用户名相同的仓库&#xff1b;并且需要添加一个 README.md自述文件即可。 如果…

nVisual在线网络规划设计软件

●01● nVisual在线网络规划设计软件 在信息化快速发展的今天&#xff0c;网络基础设施的建设与优化变得尤为关键。为了满足现代通信行业对高效、精准的网络规划需求&#xff0c;nVisual在线网络规划设计软件应运而生&#xff0c;它通过集成先进的GIS技术和网络规划工具&#…

sprinboot+vue集成neo4j图数据库

一 、java后台 1.1 package com.admin.domain;/*** 功能描述&#xff1a;** author wangwei* date 2024-01-15 22:13*/ public class ConnectWeb {private String connectWebId;private String connectWebName;private String connectWebInfo;private String personWebIdAlph…

Vue.js------Vue组件基础

能够理解Vue组件概念和作用能够掌握封装创建组件能力能够使用组件之间通信能够完成todo案例 一.Vue组件创建和使用 1.折叠面板-实现多个 创建一个文件夹demo 具体步骤请参考vue.js---vue基础 ⚫ 解决方案: 采用vue提供的单.vue文件-组件方式来封装一套然后复用 在component…

构建Python中的分布式日志系统:ELK与Fluentd的结合

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在现代软件开发中&#xff0c;日志系统是至关重要的组成部分。它们不仅用于故障排查和性能监…

利用Python进行大规模数据处理

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 利用Python进行大规模数据处理&#xff1a;Hadoop与Spark的对比 随着数据量的不断增长&…

centos linux 7.9安装php8.2.18不支持mysqli模块,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

蓝桥杯竞赛类型:Web应用开发 全程详解

既然大家准备报名蓝桥杯&#xff0c;那么对蓝桥杯就应该有一定的了解了。没有了解也没关系&#xff0c;简单来说&#xff0c;蓝桥杯就是一个计算机竞赛&#xff0c;竞赛类型大多是使用各种语言写算法&#xff0c;当然还有本文的主体——Web应用开发。对蓝桥杯有了基本了解之后&…

Https协议如何保证安全性?

Https和Http的关系 Https是Http里的一层加密层&#xff0c;如果协议走了这一层加密层&#xff0c;那么就是https。如果没有&#xff0c;则是单纯的http。 因为没有走ssl/tls这层加密层&#xff0c;所以这是单纯的http协议&#xff0c;数据在网络中传输是明文的&#xff0c;也…

用html写一个有趣的动态背景

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>一个有趣的动态背景</title><link rel"stylesheet" href"./style.css"> </head> <body> <canvas id&…

STM32 F103 C8T6开发笔记14:与HLK-LD303-24G测距雷达通信

今日尝试配通STM32 F103 ZET6与HLK-LD303-24G测距雷达的串口通信解码 文章提供测试代码...... 目录 HLK-LD303-24G测距雷达外观&#xff1a; 线路连接准备&#xff1a; 定时器与串口配置准备&#xff1a; 定时器2的初始化&#xff1a; 串口1、2初始化&#xff1a; 串口1、2自定…

【Java开发指南 | 第十五篇】Java Character 类、String 类

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 Java Character 类转义序列 Java String 类连接字符串 Java Character 类 Character 类是 Java 中用来表示字符的包装类&#xff0c;它提供了一系列静态方法用于对字符进行操作&#xff0c;其主要分为静态方法…

AAAI-24 | EarnHFT:针对高频交易的分层强化学习(RL)框架

AAAI-24 | EarnHFT:针对高频交易的分层强化学习&#xff08;RL&#xff09;框架 原创 QuantML QuantML 2024-04-15 09:25 上海 EarnHFT 摘要(Abstract):高频交易&#xff08;HFT&#xff09;使用计算机算法在短时间内&#xff08;例如秒级&#xff09;做出交易决策&#xff…

C++实战——日期类的实现

日期类的实现 前言一、日期类概念实现运用场景 二、日期类的具体实现代码构造函数拷贝构造函数获取日期&#xff08;内联函数&#xff09;赋值加等减等加减小于小于等于大于大于等于相等不相等前置后置前置- -后置- -关于类里重载的比较运算符为什么要加外部const示例 Date.hDa…

【人工智能】机器学习算法综述及常见算法详解

目录 推荐 1、机器学习算法简介 1.1 机器学习算法包含的两个步骤 1.2 机器学习算法的分类 2、线性回归算法 2.1 线性回归的假设是什么&#xff1f; 2.2 如何确定线性回归模型的拟合优度&#xff1f; 2.3 如何处理线性回归中的异常值&#xff1f; 3、逻辑回归算法 3.1 …

现代数据中心中智能网卡/DPU的演进

数据中心是一个大型的连接服务器和存储系统池&#xff0c;通常由组织用于远程存储、处理或分发大量数据。组织可以拥有和管理其数据中心&#xff0c;也可以租用由第三方&#xff08;亚马逊或谷歌云等云服务提供商&#xff09;管理的基础设施&#xff0c;并通过互联网访问资源。…

IS62LV256AL-45ULI功能参数介绍及如何优化电源稳定性以适应

IS62LV256AL-45ULI功能参数介绍-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 制造商:ISSI 产品品种:静态随机存取存储器 RoHS:是 存储容量:256 kbit 组织:32 k x 8 拜访时刻:45 ns 接口类型:Parallel 电源电压-最大:3.63 V 电源电压-最小:2.97 V 电源电流—最大值:5…