Spring之AOP理解与应用(更新中)

news2024/11/23 9:18:15

1. AOP的认识    

 面向切面编程:基于OOP基础之上新的编程思想,OOP面向的主要对象是类,而AOP面向的主要对象是切面,在处理日志、安全管理、事务管理等方面有非常重要的作用。AOP是Spring中重要的核心点,AOP提供了非常强大的功能,用来对IOC做补充。通俗点说的话就是在程序运行期间,在不修改原有代码的情况下 增强跟主要业务没有关系的公共功能代码到 之前写好的方法中的指定位置 这种编程的方式叫AOP。

        AOP在Spring框架中被用于:

  1. 提供声明式的企业服务。最重要的此类服务是 声明式事务管理。
  2. 让用户实现自定义切面,用AOP补充他们对OOP的使用。 

2. AOP核心概念和术语 

2.1 切面(Aspect)

        指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP中,切面可以使用通用类基于模式的方式(schema­based approach)或者在普通类中以@Aspect注解(@AspectJ 注解方式)来实现。

2.2  连接点(Join point)

         在程序执行过程中某个特定的点,例如某个方法调用的时间点或者处理异常的时间点。在Spring AOP中,一个连接点总是代表一个方法的执行。

2.3  通知(Advice)

         在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”, “before” and “after”等等。通知的类型将在后面的章节进行讨论。 许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。

前置通知(Before advice): 在连接点之前运行但无法阻止执行流程进入连接点的通知(除非它引发异常)。

后置返回通知(After returning advice):在连接点正常完成后执行的

通知(例如,当方法没有抛出任何异常并正常返回时)。

后置异常通知(After throwing advice): 在方法抛出异常退出时执行的通知。

后置通知(总会执行)(After (finally) advice): 当连接点退出的时候执行的通知(无论是正常返回还是异常退出)。

环绕通知(Around Advice):环绕连接点的通知,例如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它可以选择是否继续执行连接点或直接返回自定义的返回值又或抛出异常将执行结束。

2.4 切点(Pointcut)

        匹配连接点的断言。通知和切点表达式相关联,并在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用
AspectJ切点语义。

2.5 引入(Introduction)

         声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被通知的对象上。例如,可以使用引入来使bean实现 IsModified接口, 以便简化缓存机制(在AspectJ社区,引入也被称为内部类型声明(inter))。

2.6 目标对象(Target object)

         被一个或者多个切面所通知的对象。也被称作被通知(advised)对象。既然Spring AOP是通过运行时代理实现的,那么这个对象永远是一个被代理(proxied)的对象。

2.7 AOP代理(AOP proxy)

        AOP框架创建的对象,用来实现切面契约aspect contract)(包括通知方法执行等功能)。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。

2.8 织入(Weaving)

        把切面连接到其它的应用程序类型或者对象上,并创建一个被被通知的对象的过程。这个过程可以在编译时(例如使用AspectJ编译器)、类加载时或运行时中完成。 Spring和其他纯Java AOP框架一样,是在运行时完成织入的。

3. 一图理解AOP核心概念

        本节是个人对照业务需求对AOP的一些概念的解读。

        我们通过一个场景和一张图通俗的理解一下AOP的切面、通知、连接点和切入点这几个概念;

        场景: 我们有一个日志类,有before()、after()、AfterException()、afterReturn()这几个方法,我们需要记录我们的方法的日志,如果不适用AOP,那么我们就得在每个方法的前面、后面、异常调用这个日志类的方法。如果使用AOP呢? 我们如何理解呢?

        理解:

        切面指的是关注点模块化,那么我们抽出来的日志类是不是就可以理解为一个切面呢?

        切面和我们的业务方法连接的点就是连接点

        通知是运行在连接点上的动作,那么抽出来的这个日志类的方法是不是就可以理解为通知呢?

        切点是匹配连接点的断言,那就是说我们指定哪些需要增强的搭连接点就是切点

        

4. AOP的应用场景

  • 日志管理
  • 权限认证
  • 安全检查
  • 事务控制

5. 如何使用AOP

        本节会通过AOP实现日志记录的需求进行演示如何使用AOP;本案例使用的是基于注解使用AOP;

第一步: 配置AOP的依赖

     <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>

第二步:开启扫面注解

   <!--扫描包:扫描类中所有注解,不扫描注解不是生效-->
    <context:component-scan base-package="cn.learn.aop" >
    </context:component-scan>

    <!--因为我们使用的是注解方式的AOP,所以要开启注解AOP功能-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

第三步: 编写切面类

@Aspect    // 标记为切面
@Component // 标记Bean组件, 才能切入到ioc当中的bean
public class LogAspect {

    // 可以采用 声明切点的方式 让其他通知引用, 更重用性
    @Pointcut("execution(* cn.myLearnAop.service.impl.*.*(..))")
    public void pointcut(){

    }

    // 前置通知
    @Before("pointcut()")
    public void before(JoinPoint joinPoint, Logger logger){
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 所有的参数
        Object[] args = joinPoint.getArgs();

        System.out.println(logger.name()+"方法运行,参数是:"+ Arrays.asList(args)+"注解的值是:");
    }

    // 后置通知
    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 所有的参数
        Object[] args = joinPoint.getArgs();
        System.out.println(methodName+"方法运行,参数是:"+ Arrays.asList(args));
    }
    // 后置异常通知
    @AfterThrowing(value="pointcut()",
                   throwing="ex")
    public void afterThrowing(Exception ex){
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw, true));
        System.out.println("后置异常通知"+sw.getBuffer().toString());
    }
    // 后置返回通知
    @AfterReturning(value="pointcut()",
                    returning = "returnValue")
    public void afterReturning(Object returnValue){
        System.out.println("返回值:"+returnValue);
    }


    // 环绕
    @Around("pointcut()")
    public  Object arround(ProceedingJoinPoint joinPoint){
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 所有的参数
        Object[] args = joinPoint.getArgs();

        Object returnValue="";
        try {
            System.out.println("环绕:前置通知:"+methodName+"方法执行,参数:"+Arrays.asList(args));
            returnValue=joinPoint.proceed();
            System.out.println("环绕:后置通知:"+methodName+"方法执行,参数:"+Arrays.asList(args));
        } catch (Throwable throwable) {
            System.out.println("环绕:异常通知:"+throwable);
        }
        finally {
            System.out.println("环绕:返回通知:"+returnValue);
        }

        return returnValue;
    }

}

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

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

相关文章

【Python小游戏】推荐8款自由的Python游戏项目

推荐8款自由的Python游戏项目 今天给大家推荐8款不错的Python小游戏&#xff0c;这些小游戏所有项目文件&#xff08;包括所需的所有代码、图像和音频文件&#xff09;&#xff0c;给大家已经放到平台的下载频道&#xff0c;需要的可以注意一下文末的链接地址。 下面给大家简单…

Matlab进阶绘图第34期—双三角热图

在《Matlab进阶绘图第29期—三角热图》中&#xff0c;我分享过三角热图的绘制模板。 然而&#xff0c;有的时候&#xff0c;为了节省版面或者方便对比等&#xff0c;需要在一张图上绘制两个三角热图的组合形式&#xff0c;且每个三角热图使用不同的配色方案&#xff0c; 由于…

C++ 红黑树的封装

一.map/set的封装 在实现了红黑树的部分功能后&#xff0c;我们可以便可以将红黑树作为底层结构来封装map 和 set &#xff0c;但是问题也随之而来。我们都知道map是k-v的数据模型&#xff0c;而set是k的数据模型&#xff0c;我们难道要去使用两棵红黑树来封装吗&#xff1f;显…

2023年汉字小达人市级比赛最后一天的整体复习建议和5个提醒

今天是2023年11月29日&#xff0c;明天&#xff08;11月30日&#xff0c;星期四&#xff09;就是2023年汉字小达人市级活动&#xff08;市级比赛&#xff09;比赛的日子了。从孩子今天16点30放学&#xff0c;到明天16点开始比赛&#xff0c;除去生活时间、写学校作业&#xff0…

echarts图表滚动条带动页面窗口滚动条的问题

网上搜了很多方法不管用&#xff0c;后来发现每次滚动echarts或者左右滑动echarts下方都会报错&#xff0c;报错提示如下&#xff0c;看看你们的图表是否这样报错&#xff1a; 报错信息如下&#xff1a;Unable to preventDefault inside passive event listener invocation 原…

什么是Geo Trust OV证书

一、GeoTrust OV证书的介绍 GeoTrust OV证书是由GeoTrust公司提供的SSL证书&#xff0c;它是一种支持OpenSSL的数字证书&#xff0c;具有更高的安全性和可信度。GeoTrust是全球领先的网络安全解决方案提供商&#xff0c;为各类用户提供SSL证书和信任管理服务。GeoTrust OV证书…

在Springboot中操作Redis——五大数据类型

在Java中操作Redis Redis的Java客户端 前面我们讲解了Redis的常用命令&#xff0c;这些命令是我们操作Redis的基础&#xff0c;那么我们在java程序中应该如何操作Redis呢&#xff1f;这就需要使用Redis的Java客户端&#xff0c;就如同我们使用JDBC操作MySQL数据库一样。 Red…

pgsql 更新A表的x字段通过查询b表的z字段

查询表t_local_warning_hit_source的send_time 更新到表t_local_warning_source WITH t2 AS ( SELECT ID, send_time FROM t_local_warning_hit_source WHERE send_time > 2023-09-27 00:00:00 AND send_time < 2023-11-28 00:00:00 ) UPDATE t_local_warning_source t…

Web学习笔记

Web学习笔记 flask库前端基础超链接&#xff1a;空连接&#xff1a;图片&#xff1a;视频&#xff08;音频&#xff09;&#xff1a;嵌套使用列表表格格式化表格input表单系列 网络请求GET方式POST请求通过GET方式获取输入参数通过POST方式获取输入参数注册页面 CSS三种使用方式…

leetcode:2133. 检查是否每一行每一列都包含全部整数(python3解法)

难度&#xff1a;简单 对一个大小为 n x n 的矩阵而言&#xff0c;如果其每一行和每一列都包含从 1 到 n 的 全部 整数&#xff08;含 1 和 n&#xff09;&#xff0c;则认为该矩阵是一个 有效 矩阵。 给你一个大小为 n x n 的整数矩阵 matrix &#xff0c;请你判断矩阵是否为一…

Docker,从入门到精通

1、DockerFile 介绍 dockerfile 是啥?dockerfile 用来构建 docker 镜像的文件。 具体步骤&#xff1a; 1、编写一个 dockerfile 文件 2、docker build 构造一个镜像 3、docker run 运行镜像 4、docker push 发布镜像 DockerFile 构建过程 1、每个保留关键字都必须是大…

面试题:MySQL自增主键为什么不是连续的?

文章目录 前言一、自增值存储说明二、自增值修改机制三、 自增值修改时机四、 导致自增值不连续的原因4.1 唯一键冲突4.2 事务回滚4.3 批量写库操作 前言 提出这个问题&#xff0c;是因为在工作中发现 mysql 中的 user 表的 id 默认是自增的&#xff0c;但是数据库存储的结果却…

每日一练:约瑟夫生者死者小游戏

1. 问题描述 约瑟夫问题&#xff08;Josephus problem&#xff09;是一个经典的数学和计算机科学问题&#xff0c;源于犹太历史学家弗拉维奥约瑟夫斯&#xff08;Flavius Josephus&#xff09;的著作《犹太战记》。问题的描述如下&#xff1a;   在这个问题中&#xff0c;有n…

【古月居《ros入门21讲》学习笔记】13_服务数据的定义与使用

目录 说明&#xff1a; 1. 服务模型 2. 实现过程&#xff08;C&#xff09; 自定义服务数据 Person.srv文件内容 Person.srv文件内容说明 编译配置 在package.xml文件中添加功能包依赖 在CMakeLists.txt中添加编译选项 编译生成语言相关文件 创建服务器代码&#xf…

线下渠道应该如何控价

品牌渠道中的问题&#xff0c;大多跟价格有关&#xff0c;比如低价、窜货、假货&#xff0c;治理好这些价格问题&#xff0c;也就是在解决渠道中的低价问题&#xff0c;所以要先了解价格&#xff0c;再进行治理&#xff0c;这样的流程化操作&#xff0c;可以使品牌管控好渠道价…

基于单片机的烟雾检测报警装置(论文+源码)

1.系统设计 &#xff08;1&#xff09;利用传感器实现环境中温度、烟雾浓度的实时检测&#xff1b; &#xff08;2&#xff09;系统检测的各项数据信息通过液晶模块进行显示&#xff0c;提高设计可视化&#xff1b; &#xff08;3&#xff09;系统可以根据实际情况利用按键模…

【AIGC】关于Prompt你必须知道的特性

代码和数据:https://github.com/tonyzhaozh/few-shot-learning 一、实践验证的大模型的特性 1. 大模型的偏差 示例&#xff1a;&#xff08;文本的情感分析&#xff1a;一句话->P(积极&#xff09;或者N&#xff08;消极) Input: I hate this movie. Sentiment: Negativ…

winform 程序多语言

新建一个winform程序添加资源文件 在多语言的资源文件中设置key以及value设置button根据环境选择语言文件 namespace WindowsFormsMulLang {public partial class Form1 : Form{public Form1(){InitializeComponent();}public static ResourceManager rm new ResourceManager(…

重工业ERP包含哪些模块?能为企业带来哪些优势

化工、五金、重型机械制造等重工业行业的经营管理模式存在明显的差别化&#xff0c;企业内部的盘点、发货、接单、报价、委外、排产、派工单、工艺、品检等各业务数据的实时和准确共享有利于企业清晰掌握运作情况&#xff0c;及时制定经营策略&#xff0c;提高对市场变化的反应…

js实现鼠标拖拽

目录 css代码 html代码 js代码 完整代码 效果图&#xff1a; 需求&#xff1a; 鼠标在图片内按下时 图片可以跟随盒子动 鼠标弹起图片停下来 如果图片在box的盒子里面时鼠标弹起了 就把图片展示在box里面 并且让图片回到起始位置 css代码 .div {width: 100px;height: 10…