浅谈 Spring AOP 思想

news2024/9/29 15:20:13

Spring AOP

  • AOP 切面编程
    • 普通代理类
    • JDK动态代理
    • Cglib动态代理
    • AOP
      • AOP术语
      • AOP切面编程的优势
      • Advice通知类型(5种)
      • 通知的执行顺序 @Order
      • 切入点表达式
        • 表达式@execution
        • 注解@annotation
  • Spring事务管理
    • @Transactional 及 @Transactional 的两个属性
      • @Transactional 的 rollback 回滚 属性
      • @Transactional 的 propagation 传播行为 属性
  • AOP相关注解总结(十一)
    • 配置切面相关注解
    • 通知相关注解
    • 事务相关注解

AOP 切面编程

AOP 底层是基于动态代理思想实现的 可以把核心业务业务逻辑看作是一个圆增强的业务逻辑也看成是一个圆,核心业务逻辑在增强的业务逻辑的中央,这样就形成了一个同心圆(切面), 这种编程思想的好处是 无侵入 即 不会对源码进行修改。以一个为核心业务逻辑增加日志的例子来逐步引出动态代理和AOP面向切面编程思想。

普通代理类

最原始的方式是利用代理类的方式为核心业务逻辑增添打印日志的功能,这就要求被代理类和增强类要同时实现一个接口来保证方法的一致性,但是还需要为每一个代理类都创建一个对象,当增强的方法都相同时就造成了代码的重复编写,造成了开发效率的降低。下面这种是修改源码的方式。
在这里插入图片描述
在这里插入图片描述

目前代码存在两个问题
代码耦合性高:业务代码和日志代码耦合在了一起
代码复用性低:日志代码在每个方法都要书写一遍

在这里插入图片描述

JDK动态代理

为了解决基本代理方式的不足,产生了JDK动态代理的方式,但是这样的方式还有一个不足,就是只能对接口的实现类进行代理,在此背景下,Cglib动态代理又出现了,Cglib动态代理可以为类动态创建代理类。
PS: 在创建代理对象时 jdk的速度要高于cglib
所以选择的时候:
当被代理类有接口的时候,使用jdk动态代理
当被代理类没有接口的时候,使用cglib动态代理

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class DeptServiceTest {

    @Autowired
    private DeptService deptService;

    @Autowired
    private Logger logger;

    @Test
    public void test1() {

        InvocationHandler myHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                logger.m1();

                try {

                    method.invoke(deptService,args);

                } catch (Exception e) {

                    logger.m3();
                }
                logger.m2();

                return null;
            }
        };


      DeptService deptServiceproxy = (DeptService) Proxy.newProxyInstance(
                deptService.getClass().getClassLoader(),
                new Class[]{DeptService.class},
               myHandler
        );


        deptServiceproxy.save(null);
        deptServiceproxy.findAll();
        deptServiceproxy.findById(null);
    }

}

在这里插入图片描述

Cglib动态代理

在这里插入图片描述

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class DeptServiceTest {


    @Autowired
    private DeptServiceImpl deptService;

    @Autowired
    private Logger logger;

    @Test
    public void test01() {

        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                logger.m1();

                try {
                    method.invoke(deptService, args);
                } catch (Exception e) {
                    logger.m3();
                }
                logger.m2();
                return null;
            }
        };


        DeptServiceImpl deptServiceProxy = (DeptServiceImpl) Enhancer.create(DeptServiceImpl.class, invocationHandler);
        //注意: Enhancer有个硬伤,就是无法对已经封装过的targetclass,再继续封装多一次,无法实现多个interceptor的链式调用。


        deptServiceProxy.findAll();
        System.out.println("=============================");
        deptServiceProxy.save(null);
        System.out.println("=============================");
        deptServiceProxy.findById(null);
    }
}

首先通过enhancer创建代理类,再创建代理类的实例对象
在这里插入图片描述

AOP

切面类要使用两个注解 @Component 和 @Aspect 声明该类为一个切面类,并且将该切面类加入到Spring容器中,在切面类中可以定义切点 @ PointCut()和通知 (5种),下面会展开详细叙述
在这里插入图片描述

AOP术语

在这里插入图片描述

AOP切面编程的优势

在这里插入图片描述

Advice通知类型(5种)

@Before:前置通知,此注解标注的通知方法在目标方法前被执行
@AfterReturning: 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
@AfterThrowing: 异常后通知,此注解标注的通知方法发生异常后执行
@After:后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行

@Around

@Around环绕通知需要自己调用 ProceedingJoinPoint.proceed() 来让原始方法执行,其他通知不需要考虑目标方法执行
@Around环绕通知方法的返回值,必须指定为Object,来接收原始方法的返回结果  Object result = pjp.proceed();

通知的执行顺序 @Order

不同切面类中,默认按照切面类的全类名字母排序:
目标方法前的通知方法:字母排名靠前的先执行
目标方法后的通知方法:字母排名靠前的后执行
相当于一个嵌套的效果一样,类比Filter中的过滤器链的执行顺序,也是按照全类名字母靠前的先执行

切入点表达式

切入点表达式:描述切入点方法@PointCut()的一种表达式
作用:主要用来决定项目中的哪些方法需要加入通知
常见形式:
在这里插入图片描述

表达式@execution

execution(……):根据方法的签名来匹配,常与通配符(* 和 …)搭配使用 ,…用在参数表示0或n个参数 *模糊匹配

使用切入点表达式 需要指定 权限修饰符 返回值类型 方法名的全名(带全类名) 参数 ,因此excution常与通配符搭配用来定义方法名有规律的切入点
在这里插入图片描述

注解@annotation

@annotation(……) :根据注解匹配,使用注解方式,需要自定义注解,常用来定义方法名无规律的切入点pointcut,自定义注解,如下所示:@annotation(注解全类名)

在这里插入图片描述

在切点配置自定义注解,用于识别对那些方法进行增强
在这里插入图片描述
配置切点注解
在这里插入图片描述

Spring事务管理

在Spring容器中使用事务时还需要在Spring配置类中配置@EnableTransactionMangement注解和@Bean配置事务管理器
在这里插入图片描述

@Transactional 及 @Transactional 的两个属性

位置:业务(service)层的方法上、类上、接口上
作用:将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务

注解用在方法上,表示为方法开启事务,用在类上表示为类中所有方法开启事务,用在接口上表示为接口的所有实现类开启事务

@Transactional 的 rollback 回滚 属性

默认情况下,只有出现 RuntimeException 才回滚异常,rollbackFor属性用于控制让非运行时异常也回滚。
因此,需要为 @Transactional的rollback属性指定异常类类型让其对所有异常都进行回滚
在这里插入图片描述

@Transactional 的 propagation 传播行为 属性

事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。通俗点说就是:一个有事务注解修饰的方法在被另一个开启了事务的方法调用时,该方法的事务怎么办的问题。默认值是required

在这里插入图片描述
2中比较常用的是 required (默认) 有事务就加入,无事务就创建新的 和 requires_new 事务不影响
在这里插入图片描述

AOP相关注解总结(十一)

配置切面相关注解

@Component

@Aspect

@PointCut

@annotation

通知相关注解

@Before
@AfterReturning
@AfterThrowing
@After
@Around
@Oredr

事务相关注解

@EnableTransactionMangement

@Transactional

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

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

相关文章

AR开发平台 | 探索AR技术在建筑设计中的创新应用与挑战

随着AR技术的不断发展和普及,越来越多的建筑师开始探索AR技术在建筑设计中的应用。AR(增强现实)技术可以通过将虚拟信息叠加到现实场景中,为设计师提供更加直观、真实的建筑可视化效果,同时也可以为用户带来更加沉浸式的体验。 AR开发平台广…

SpringBoot项目连接数据库

1、找到applications.yml,如下图 2、写入代码 server:port: 9494spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/自己的数据库表名?serverTimezoneGMT%2b8username: rootpassword: root

短视频矩阵源码开发搭建分享--多账号授权管理

目录 文章目录 前言 一、矩阵号系统是什么? 二、使用步骤 1.创建推广项目 2.多账号授权 3.企业号智能客服系统 总结 前言 短视频多账号矩阵系统,通过多账号一键授权管理的方式,为运营人员打造功能强大及全面的“矩阵式“管理平台。…

修改整数(有点坑,所以发出来了)

问题描述 小贝给了小聪一个正整数 x,但是小聪决定把这个数改掉。她可以把整数 x 每个位置上的数 t 改成 9-t。 请你帮助小聪来计算一下,如何把 x 改成一个最小的正整数,注意,不能出现首位为 0 的情况。 输入格式 输入一个正整数…

Vue通过指令 命令将打包好的dist静态文件上传到腾讯云存储桶 (保存原有存储目录结构)

1、在项目根目录创建uploadToCOS.js文件 (建议起简单的名字 方便以后上传输入命令方便) 2、uploadToCOS.js文件代码编写 const path = require(path); const fs = require(fs); const COS = require(cos-nodejs-sdk-v5);// 配置腾讯云COS参数 const cos = new COS({SecretI…

NoSQL-Redis集群

NoSQL-Redis集群 一、集群:1.单点Redis带来的问题:2.解决:3.集群的介绍:4.集群的优势:5.集群的实现方式: 二、集群的模式:1.类型:2.主从复制: 三、搭建主从复制&#xff…

vscode 打开文件时如何在资源管理器中展开文件所在的整个目录树(包含node_modules)

如题。去 首选项 --> 设置 中 搜索 “Auto Reveal”,然后选true,注意把下面的Auto Reveal Exclude排除项中的node_modules去掉,这样才能定位到node_modules中的文件。 **/node_modules

【FPGA IP系列】FIFO的通俗理解

FPGA厂商提供了丰富的IP核,基础性IP核都是可以直接免费调用的,比如FIFO、RAM等等。 本文主要介绍FIFO的一些基础知识,帮助大家能够理解FIFO的基础概念。 一、FIFO介绍 FIFO全称是First In First Out,即先进先出。 FIFO是一个数…

函数重载与引用

文章目录 一、函数重载1. 重载规则2.重载列子3.函数名修饰规则 二、引用1.本质2.特性1. 引用必须在定义时初始化2 . 一个变量可以有多个引用3 . 引用一旦引用一个实体,就不能引用其他实体 3.引用例子4.引用的权限5.效率比较6.指针跟引用的区别 一、函数重载 函数重…

我的创作纪念日 --- 鲁迅文学无聊版

机缘 ------从第一次使用CSDN这个网站到现在已经快四年了,我大抵是病了,2021年7月29日才心血来潮写下来了第一篇自己的博客,回顾起来,已经过去了2年。如此这般,断断续续的写过一些博客,但终归是心血来潮罢了…

【Docker】Docker的优势、与虚拟机技术的区别、三个重要概念和架构及工作原理详细讲解

前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 作者简介: 辭七七&#xf…

PS - Photoshop 实现涂抹功能 (橡皮擦、图章、吸管、画笔)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/131997323 在 Photoshop 中,橡皮擦工具,以及吸管工具和画笔工具可以配合使用,实现涂抹功能,再通过…

第四届世界蜂疗大会在中国·重庆武隆盛大开幕

【39蜂疗网】记者 讯 7月25日至27日,“世界中联蜂疗专业委员会第五届学术年会暨第四届世界蜂疗大会、中国民族医药学会蜂疗分会2023年学术年会”在重庆武隆正式启幕。开幕式上,重庆市政府副市长但彦铮宣布开幕;人民英雄、中国工程院院士张伯礼…

QPainter绘制雷达界面

文章目录 功能实现定义的结构体定义的函数效果图gitee源码链接 功能实现 相较于上一版,这一版添加的功能有: 1、自适应窗口 2、扫描方式(圆周扫描、扇形扫描(指定起始角度和结束角度)) 3、扫描方向&#x…

WITH AS 的 sql语法是啥意思

WITH t1 AS ( select * from my_table_1 where age >30 ), t2 AS ( select * from my_table_2 where sex M ) select * from t1 inner join t2 on t1.id t2.t_id;WITH AS 的 sql语法是啥意思? WITH和AS是SQL语句中的关键字,用于创建临时命名的查询…

hcip——路由策略

要求: 基础配置 AR1 [R1]int g 0/0/0 [R1-GigabitEthernet0/0/0]ip add 12.0.0.1 24[R1-GigabitEthernet0/0/0]int g 0/0/1 [R1-GigabitEthernet0/0/1]ip add 14.0.0.1 24[R1]int loop0 [R1-LoopBack0]ip add 1.1.1.1 24[R1]rip 1 [R1-rip-1]vers 2 [R1-rip-1]net…

RS485/RS232自由转ETHERNET/IP网关profinet和ethernet区别

你是否曾经遇到过这样的问题:如何将ETHERNET/IP网络和RS485/RS232总线连接起来呢?捷米的JM-EIP-RS485/232通讯网关,自主研发的ETHERNET/IP从站功能,完美解决了这个难题。这款网关不仅可以将ETHERNET/IP网络和RS485/RS232总线连接起…

mysql(六)读写分离

目录 前言 一、概述 二、配置JAVA环境及安装阿米巴 三、配置阿米巴 四、测试 总结 前言 MySQL读写分离是一种常见的数据库架构设计模式,旨在提高系统的性能和可用性。它通过将读操作和写操作分离到不同的MySQL实例上来实现。 读写分离的原理是: 1. 主…

容器化安装环境EFK搭建

容器化安装环境 Docker中安装并启动ElasticSearch 前置配置 第一步:在宿主机上执行echo “net.ipv4.ip_forward1” >>/usr/lib/sysctl.d/00-system.conf 2.第二步:重启network和docker服务 [rootlocalhost /]# systemctl restart network &&…

Linux - PostgreSQL 适用于9.x 以上的 tar.gz 源码安装与理解 - 报错集锦

这里写目录标题 序言主要内容bash 配置文件个人理解关于初始化 PostgreSQL 数据库的理解 启动方法检查服务器是否在PostgreSQL中运行关闭 postgresql 数据库方法参考链接 序言 PostgreSQL 9.x 以下版本笔者没用过,具体操作看参考链接,笔者就不记录重复操…