Spring第七天(AOP)

简介

AOP(Aspect Oriented Programing)面向切面编程,一种编程范式,指导开发者如何组织程序结构

作用

不惊动原始设计的基础上为其进行功能增强

Spring理念:无入侵式/无侵入式

基本概念

连接点(JoinPoint) : 程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等

        在SpringAOP中,理解为方法的执行

切入点(Pointcut) : 匹配连接点的式子

        在SpringAOP中,一个切入点只描述一个具体方法,也可以匹配多个方法

                一个具体方法:e.g.:dao类中的save方法

                匹配多个方法:所有的save方法,所有以get开头的方法,所有以Dao结尾的接口中的任                  意方法,所有带有一个参数的方法

通知(Advice) : 在切入点执行的操作,也就是共性功能

        在SpringAOP中,功能最终以方法的形式呈现

通知类:定义通知的类

切面(Aspect) : 描述通知与切入点的对应关系

实现案例

第一步、导入相关坐标

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
    </dependencies>

第二步、定义dao接口与其实现类

package com.cacb.dao.impl;

import com.cacb.dao.BookDao;
import org.springframework.stereotype.Repository;

@Repository
public class BookDaoImpl implements BookDao {
    @Override
    public void save() {
        System.out.println(System.currentTimeMillis());
        System.out.println("BookDao saving!");
    }

    @Override
    public void update() {
        System.out.println("BookDao updating!");

    }
}

第三步、定义通知类,制作通知

public class MyAdvice {
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

第四步、在通知类中定义切入点

public class MyAdvice {
    @Pointcut("execution(void com.cacb.dao.BookDao.update())")
    private void pt(){}

    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

注:

切入点定义依托一个不具有实际意义的方法进行,即无参数,无返回值,方法体无实际逻辑

第五步、在通知类中绑定切入点预通知关系,并指定通知添加到原始连接点的具体执行位置

public class MyAdvice {
    @Pointcut("execution(void com.cacb.dao.BookDao.update())")
    private void pt(){}


    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

第六步、定义通知类受Spring容器管理,并定义当前类为切面类 

@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(void com.cacb.dao.BookDao.update())")
    private void pt(){}


    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

第七步、在Spring核心配置文件中开启Spring对AOP注解驱动支持

@Configuration
@ComponentScan("com.cacb")
@EnableAspectJAutoProxy
public class SpringConfig {
}

AOP工作流程

1.Spring容器启动

2.读取所有切面配置中的切入点

3.初始化Bean,判定Bean对应的类中的方法是否匹配到任意切入点

        匹配失败,则创建对象

        匹配成功,则创建原始对象(目标对象)的代理对象

4.获取Bean执行方法

        获取Bean,调用方法并执行,完成操作

        获取的Bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

目标对象(Target) : 原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的

代理(Proxy) : 目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象实现

APO切入点表达式

切入点:要进行增强的方式

切入点表达式:要进行增强的方法的描述方式

以上例update()方法为例,共有两种描述方式

方式一:接口方式

@Pointcut("execution(void com.cacb.dao.BookDao.update())")

方式二:实现类方式

@Pointcut("execution(void com.cacb.dao.impl.BookDaoImpl.update())")

切入点表达式标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名 (参数)异常名)

动作关键字:描述切入点的行为动作,例如execution表示执行到指定切入点

访问修饰符:public,private等,可以省略

异常名:方法定义中抛出指定异常,可以省略

通配符

可以使用通配符描述切入点,快速描述

 * 单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现

execution(public * com.cacb.*.UserService.find* (*))

匹配com.cacb包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法

.. 多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

execution(public User com..UserService.findById (..))

匹配com包下的任意包中的UserService类或者接口中的所有名称为findById的方法

+ 专用于匹配子类类型

execution(* * ..*Service+.* (..))

AOP通知类型

AOP通知描述了抽取的共性功能,根据共性功能抽取的位置不同,最终运行代码时要将其加入到合理的位置

AOP通知共分为五种类型

前置通知

@Before("")

后置通知

@After("")

环绕通知

    @Around("")
    public void around(ProceedingJoinPoint pjp) throws Throwable{
        //..原方法前操作
        pjp.proceed(); //表述对原始操作的调用
        //..原方发后操作
    }

如果原方法有返回值 

    @Around("")
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        //..原方法前操作
        Object result = pjp.proceed(); //表述对原始操作的调用
        //..原方法后操作
        return result
        
        
    }

返回后通知

@AfterReturning("")

只有在调用方法没有抛出异常,正常运行结束后该通知才会运行 

抛出异常后通知

@AfterThrowing("")

只有在调用方法抛出异常后才会运行

@Around注意事项

1.环绕通知必须依赖形参ProceedingJoinPoint才能实现对原始方法的调用,进而实现原始方法调用前后同时添加通知

2.通知中如果未使用ProceedingJoinPoint对原始方法进行调用将跳过原始方法的执行

3.对原始方法的调用可以不接收返回值,通知方法设置成void即可,如果接收返回值,必须设定为Object类型

4.原始方法的返回值如果是void类型,通知方法的返回值类型可以设置成void,也可以设置成Object

5.由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throwable对象

AOP通知获取数据

获取参数

JoinPoint:适用于前置、后置、返回后、抛出异常后通知

ProceedingJoinPoint:适用于环绕通知

获取返回值

返回后通知

环绕通知

获取异常

抛出异常后通知

 

环绕通知

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云盘后端分析

1.验证码 用的是外面找的 2.发送邮箱验证码 配置邮箱的授权码 我们在发送邮箱的时候&#xff0c;需要把那个值传到数据库中&#xff0c;数据库中有它的状态&#xff0c;我们需要根据状态判断它是注册还是找回密码 我们在发送邮箱之前&#xff0c;先从session里面得到我们验证…

wayland(xdg_wm_base) + egl + opengles 最简实例

文章目录 前言一、ubuntu 下相关环境准备1. 获取 xdg_wm_base 依赖的相关文件2. 查看 ubuntu 上安装的opengles 版本3. 查看 weston 所支持的 窗口shell 接口种类二、xdg_wm_base 介绍三、egl_wayland_demo1.egl_wayland_demo2_0.c2.egl_wayland_demo3_0.c3. xdg-shell-protoco…

Node开发基础

1. 概述 1.1 为什么要学习服务器端开发基础 能够和后端程序员更加紧密的配合 网站业务逻辑前置&#xff0c;学习前端技术需要后端技术支撑 扩宽知识视野&#xff0c;能够站在更高的角度审视整个项目 1.2 服务器端开发要做的事情 实现网站的业务逻辑 ---网站登录部分&#…

[pytorch入门] 2. tensorboard

tensorboard简介 TensorBoard 是一组用于数据可视化的工具。它包含在流行的开源机器学习库 Tensorflow 中.但是也可以独立安装&#xff0c;服务Pytorch等其他的框架 可以常常用来观察训练过程中每一阶段如何输出的 安装pip install tensorboard启动tensorboard --logdir<d…

LeetCode面试题05.06

美好的一天&#xff0c;从力扣开始 王子公主请看题 整数转换。编写一个函数&#xff0c;确定需要改变几个位才能将整数A转成整数B。 示例1: 输入&#xff1a;A 29 &#xff08;或者0b11101&#xff09;, B 15&#xff08;或者0b01111&#xff09;输出&#xff1a;2示例2: 输…

深度求索开源国内首个 MoE 大模型 | DeepSeekMoE:在专家混合语言模型中实现终极专家专业化

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 在大语言模型时代&#xff0c;混合专家模型&#xff08;MoE&#xff09;是一种很有前途的架构&#xff0c;用于在扩展模型参数时管理计算成本。然而&a…

【算法专栏学习】成贤学院,程序员的福利站到了,判断子序列,经典算法实战。

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

使用宝塔面板安装wiki.js详细教程

因为在安装过程中遇到了一些问题&#xff0c;花费了很长时间在解决问题上。根据这篇教程可以少踩很多坑。点赞加关注吧。 准备运行环境 Nodejs 在宝塔面板的软件商店中找到nodejs版本管理器并安装。 点击设置&#xff0c;选择一个稳定版安装。 PostgreSQL 官方推荐的数据库是…

Nginx之负载均衡、静态代理与动态代理配置

Nginx之负载均衡配置 文章目录 Nginx之负载均衡配置1. 负载均衡基本配置1. 配置upstream2. 配置location3. 访问 2. Nginx常用负载均衡策略1. 轮询(默认)2. 权重3. ip_hash策略4. 最少连接策略5. 负载均衡其他几个配置 3. 静态代理1. 基于静态在一文件后缀的匹配2. 基于静态资源…

Python - 深夜数据结构与算法之 高级字符串

目录 一.引言 二.经典算法实战 1.Longest-Common-Sub-Seq [1143] 2.Edit-Distance [72] 3.Longest-Palindromic-Str [5] 4.Distinct-Sub-Seq [115] 5.Regular-Exp-Match [10] 三.总结 一.引言 上一节介绍了字符串的基本操作&#xff0c;本文介绍字符串更复杂的一些操作…

YOLOv8改进 | 主干篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是低照度图像增强网络SCINet,SCINet(自校正照明网络)是一种专为低光照图像增强设计的框架。它通过级联照明学习过程和权重共享机制来处理图像,优化了照明部分以提升图像质量。我将该网络集成在YOLOv8的主干上针对于图像的输入进行增…

BurpSuite Pro 2023.12.1.2下载与破解-最新版BurpSuite Pro

本文在我的博客地址是&#xff1a;https://h4cker.zip/post/f05ae2e66da503f6383dffe48cdf5bac 上一次BurpSuite的分享还是在2020年 由于CSDN有防盗链&#xff0c;我自己的博客都无法访问这篇博文的图片了 至于为什么再写一次&#xff0c;是因为我看到群里这张图&#xff1a;…

高效能方法 - 任务清单优先级

任务清单是有优先级的&#xff0c;首先要尽所能保证A级别的事项完成&#xff0c;或许不能估计B级或者C级&#xff0c;那这结果也是不错的。 博恩崔西在《吃掉那只青蛙》一书中指出&#xff1a;在你决定要做什么&#xff0c;并对其进行排序的时候&#xff0c;你首要解决那些最难…

腾讯云服务器价格查询,2024更新

腾讯云服务器租用优惠价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器646元15个月&#xff1b;云服务器CVM S5实例2核2G配置280.8元一年、2核4G…

x-cmd pkg | yq - 命令行 YAML处理工具

目录 简介首次用户支持格式转换友好的显示和操作语法与 jq 类似竞品和相关作品进一步阅读 简介 yq (YAML Query) 是一个轻量级的 YAML、JSON、XML 处理器&#xff0c;主要用于查询和提取 YAML 数据。 本 yq 的包来自 mikefarah/yq 项目&#xff0c;语法类似于 jq 。相比 kisly…

《WebKit 技术内幕》之八(2):硬件加速机制

2 Chromium的硬件加速机制 2.1 GraphicsLayer的支持 GraphicsLayer对象是对一个渲染后端存储中某一层的抽象&#xff0c;同众多其他WebKit所定义的抽象类一样&#xff0c;在WebKit移植中&#xff0c;它还需要具体的实现类来支持该类所要提供的功能。为了完成这一功能&#x…

python if条件判断的基础及应用

当前版本&#xff1a; Python 3.8.4 简介 if 语句是一种用于根据一个或多个条件的结果来执行不同代码块的控制流结构&#xff0c;它会检查给定的条件是否为真。如果条件为真&#xff0c;则执行与之关联的代码块&#xff1b;如果条件为假&#xff0c;则执行与之关联的其他代码块…

工作小计- RGB相关算子实现

项目中的模型一直都是直接操作NV12的yuv格式数据&#xff0c;这次的模型只支持RGB格式的输入&#xff0c;正好来自己实现对应的算子。 这里记录一下对应算子的实现过程&#xff0c;主要涉及到NV12到RGB的变换&#xff0c;RGB的crop/resize操作&#xff0c;对于数据的Norm/ToFlo…

python 正则表达式学习(1)

正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与某种模式匹配。 1. 特殊符号 1.1 符号含义 模式描述^匹配字符串的开头$匹配字符串的末尾.匹配任意字符&#xff0c;除了换行符&#xff0c;当re.DOTALL标记被指定时&#xff0c;则可以匹配包…

芯片工程系列(1)封装基础知识、分来、步骤与方法.md

英文缩写 环氧树脂模塑料&#xff08;Epoxy Molding Compound&#xff0c;EMC&#xff09;引线框架封装&#xff08;Leadframe&#xff09;&#xff0c;基板封装&#xff08;Substrate&#xff09;&#xff0c;Substrate 基板晶圆片级芯片规模封装&#xff08;Wafer Level Chi…