【Spring】Spring框架之-AOP

目录

1. AOP的引入

2. AOP相关的概念

2.1 AOP概述

2.2 AOP的优势

2.3. AOP的底层原理--目前先不具体阐述,后面讲

 3. Spring的AOP技术-配置文件方式

3.1 AOP相关的术语

3.2 基本准备工作

3.3 AOP配置文件方式的入门

3.4 切入点的表达式

 3.5 AOP的通知类型

1. 前置通知

2. 环绕通知

3. 最终通知

4.  后置通知

 4. Spring的AOP技术-注解方式

4.1. AOP注解方式入门程序

1. 配置xml扫描注解

2. 配置注解 

3. 配置文件中开启自动代理

4. 通知类型注解


1. AOP的引入

首先我们来看一下登录的原理

        如上图所示这是一个基本的登录原理图,但是如果我们想要在这个登录之上添加一些新的功能,比如权限校验

那么我们能想到的就有两种方法:

①:通过对源代码的修改实现 

②:不通过修改源代码方式添加新的功能 (AOP)

 


2. AOP相关的概念

2.1 AOP概述

什么是AOP的技术?

        在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程

        AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构。

        AOP最早由AOP联盟的组织提出的,制定了一套规范.  Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范。

        通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术。

        AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。

        利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.

        AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(事务管理、安全检查、缓存)

为什么要学习AOP?

        可以在不修改源代码的前提下,对程序进行增强!!-->也就是增加功能

2.2 AOP的优势

运行期间,不修改源代码的情况下对已有的方法进行增强

优势:

        1. 减少重复的代码

        2. 提供开发的效率

        3. 维护方便

2.3. AOP的底层原理--目前先不具体阐述,后面讲

JDK的动态代理技术

        1、为接口创建代理类的字节码文件

        2、使用ClassLoader将字节码文件加载到JVM

        3、创建代理类实例对象,执行对象的目标方法

cglib代理技术

        为类生成代理对象,被代理类有没有接口都无所谓,底层是生成子类,继承被代理类。


 3. Spring的AOP技术-配置文件方式

3.1 AOP相关的术语

        Joinpoint(连接点) 类里面有哪些方法可以增强这些方法称为连接点。

        Pointcut(切入点) -- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义。

        Advice(通知/增强)-- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)。

        Aspect(切面)-- 是 切入点+通知 的结合,以后咱们自己来编写和配置的。

 

        成熟的不能作为连接点,但是成熟的没见过,就是都能作为连接点。

        增加功能的代码就是增强。

        try-catch-finally,finally永远都会执行。


3.2 基本准备工作

        AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,AspectJ实际上是对AOP编程思想的一个实践。

3.3 AOP配置文件方式的入门

$1. 创建maven项目,坐标依赖

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--AOP联盟--><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!--Spring Aspects--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version></dependency><!--aspectj--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.3</version></dependency>
</dependencies>

 注意!!

        我这里Maven配置时 aspectj 是空项目,就是之前没有下载,因此一直报错。

        如果你也一直报错,右键鼠标,点击Maven,下载资源即可解决!!

 $2. 创建被增强的类

public class Cat {public void add(int nums){System.out.println("添加了"+nums);}public void delete(int nums){System.out.println("删除了"+nums);}public void update(){System.out.println("进行了修改");}public void login(String username,String password){System.out.println("进行数据库对比");}}

         我们在登录时增加权限验证。

$3. 将目标类配置到Spring中。

<bean name="cat" class="com.qcby.service.Cat"/>

$4. 定义切面类

public class 权限 {public void 验证(){System.out.println("进行权限验证");}
}

$5. 在配置文件中定义切面类

<bean name="qx" class="com.qcby.service.权限"/>

$6. 在配置文件中完成AOP的配置

<!--pointcut:后边是切入点表达式,作用是知道对对面的那个方法进行增强-->

<aop:config><!--配置切面 = 切入点 + 通知组成--><aop:aspect ref="qx"><aop:before method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/><!--after:最终通知finally(无论成功或失败都会执行)-->
<!--            <aop:after method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>-->
<!--            <aop:after-returning method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>-->
<!--            <aop:after-throwing method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>--><!--                <aop:around method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>--></aop:aspect></aop:config>

$7. 测试test

public class Test2 {@Testpublic void test(){ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("Spring.xml");Cat cat=(Cat) ac.getBean("cat");cat.login("小猫","1245");}
}


3.4 切入点的表达式

再配置切入点的时候,需要定义表达式,具体展开如下:

        切入点表达式的格式如下:

                execution([修饰符] [返回值类型] [类全路径] [方法名 ( [参数] )])

 其中,

        修饰符可以省略不写,不是必须要出现的。

        返回值类型是不能省略不写的,根据你的方法来编写返回值,可以使用 * 代替。

包名,类名,方法名,参数的规则如下:

例如

        com.qcby.demo3.BookDaoImpl.save()

1. 首先包名,类名,方法名是不能省略不写的,但是可以使用 * 代替

2. 中间的包名可以使用 * 号代替

3. 类名也可以使用 * 号代替,也有类似的写法:*DaoImpl

4. 方法也可以使用 * 号代替

5. 参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 ..

比较通用的表达式

                execution(* com.qcby.*.ServiceImpl.save(..))

举例2

        com.qcby.demo3.BookDaoImpl当中所有的方法进行增强

                        execution(* com.qcby.*.ServiceImpl.*(..))

举例3

        com.qcby.demo3包当中所有的方法进行增强

                        execution(* com.qcby.*.*.*(..))


 3.5 AOP的通知类型

1. 前置通知

目标方法执行前,进行增强。

        如上配置案例就是前置通知。

2. 环绕通知

目标方法执行前后,都可以进行增强。

目标对象的方法需要手动执行。

// 环绕通知
public void 验证(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("before.............");//  执行被增强的方法proceedingJoinPoint.proceed();System.out.println("after.............");
}

xml配置

<aop:around method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>

3. 最终通知

目标方法执行成功或者失败,进行增强。

public class Cat {public void add(int nums){System.out.println("添加了"+nums);}public void delete(int nums){System.out.println("删除了"+nums);}public void update(){System.out.println("进行了修改");}public void login(String username,String password){int a=10/0;System.out.println("进行数据库对比");}}
public class 权限 {public void 验证(){System.out.println("进行权限验证");}
}

xml配置

<aop:after method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>

测试:         

        切入点有错误还是进行了增强。 

4.  后置通知

目标方法执行成功后,进行增强。

目标文件配置

public void login(String username,String password){int a=10/0;System.out.println("进行数据库对比");}

xml配置

<aop:after-returning method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>

目标方法有错误,不进行增强。 

改正后: 

 public void login(String username,String password){
//        int a=10/0;System.out.println("进行数据库对比");}

可以进行增强。

5. 异常通知

目标方法执行失败后,进行增强。(发生异常的时候才会执行,否则不执行)

目标文件

public void login(String username,String password){int a=10/0;System.out.println("进行数据库对比");}

xml配置: 

<aop:after-throwing method="验证" pointcut="execution(public void com.qcby.service.Cat.login(..))"/>

测试

若目标文件改正确之后,

不进行增强


 4. Spring的AOP技术-注解方式

4.1. AOP注解方式入门程序

创建maven工程,导入坐标。编写接口,完成IOC的操作。步骤略。

编写切面类

给切面类添加注解 @Aspect,编写增强的方法,使用通知类型注解声明。

1. 配置xml扫描注解

<!--开启注解扫描--><context:component-scan base-package="com.qcby"></context:component-scan>

2. 配置注解 

给切面类添加注解 @Aspect,编写增强的方法,使用通知类型注解声明

@Component
@Aspect  //生成代理对象
public class 权限 {public void 验证(){System.out.println("进行权限验证");}
}
@Component
public class Cat {public void add(int nums){System.out.println("添加了"+nums);}public void delete(int nums){System.out.println("删除了"+nums);}public void update(){System.out.println("进行了修改");}public void login(String username,String password){
//        int a=10/0;System.out.println("进行数据库对比");}}

3. 配置文件中开启自动代理

<!--开启Aspect生成代理对象--><aop:aspectj-autoproxy></aop:aspectj-autoproxy>

4. 通知类型注解

@Before -- 前置通知

@AfterReturing -- 后置通知

@Around -- 环绕通知(目标对象方法默认不执行的,需要手动执行)

@After -- 最终通知

@AfterThrowing -- 异常抛出通知

 @Before -- 前置通知

@Before(value = "execution(public void com.qcby.service.Cat.login(..))")public void before(){System.out.println("before.............");}

 @AfterReturing -- 后置通知

@AfterReturning(value = "execution(public void com.qcby.service.Cat.login(..))")public void 验证(){System.out.println("before.............");}

@Around -- 环绕通知(目标对象方法默认不执行的,需要手动执行) 

@Around(value = "execution(public void com.qcby.service.Cat.login(..))")public void before(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{System.out.println("before.............");//  执行被增强的方法proceedingJoinPoint.proceed();System.out.println("after.............");}

@After -- 最终通知 

@After(value = "execution(public void com.qcby.service.Cat.login(..))")public void 验证(){System.out.println("before.............");}

@AfterThrowing -- 异常抛出通知 

@AfterThrowing(value = "execution(public void com.qcby.service.Cat.login(..))")public void 验证(){System.out.println("before.............");}

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

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

相关文章

Servlet学习中遇到的一些问题及解决

错误&#xff1a;JavaWeb-错误&#xff1a;类xxx不是Servlet 解决&#xff1a;可能是Tomcat版本不匹配导致&#xff0c;更换Tomcat版本解决问题 错误&#xff1a;在自定义的Servlet类中不能添加 WebServlet 注解 解决&#xff1a;可能是WebServlet版本不匹配&#xff0c;更换…

tomcat的安装以及配置(基于linuxOS)

目录 安装jdk环境 yum安装 验证JDK环境 安装tomcat应用 yum安装 ​编辑 使用yum工具进行安装 配置tomcat应用 关闭防火墙和selinux 查看端口开启情况 ​编辑 访问tomcat服务 安装扩展包 重启服务 查看服务 源码安装 进入tomcat官网进行下载 查找自己要用的to…

workman服务端开发模式-应用开发-gateway长链接端工作原理

一、长链接的工作原理 Register类其实也是基于基础的Worker开发的。Gateway进程和BusinessWorker进程启动后分别向Register进程注册自己的通讯地址&#xff0c;Gateway进程和BusinessWorker通过Register进程得到通讯地址后&#xff0c;就可以建立起连接并通讯了。而Gateway进程…

Chrome 浏览器原生功能截长屏

我偶尔需要截取一些网页内容作为素材&#xff0c;但偶尔内容很长无法截全&#xff0c;需要多次截屏再拼接&#xff0c;过于麻烦。所以记录下这个通过浏览器原生功能截长屏的方案。 注意 这种方案并不是百分百完美&#xff0c;如果涉及到一些需要滚动加载的数据或者悬浮区块&am…

Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)

Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版) 文章目录 Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)一.环境准备1.服务器准备2.环境配置3.设置主机名4.修改国内镜像源地址5.配置时间同步6.配置内核转发及网桥过滤二.容器运行时Containerd安装(所有节点)…

Nuc9 Truenas 和 Macmini4组雷电网桥 上传速度异常 1Mbp/s 解决

link: 原创文章&#xff0c;转载之前请标注来源博客 helsonlin 前言 咸鱼整了一台 Nuc9 组了全闪的 Nas&#xff0c;想着和 Macmini 组雷电网桥&#xff0c;但是到手弄好之后发现 iperf3 和 openspeedtest 测试上传的速度都是 1Mbps 每秒。 Google 一下发现唯一的线索就是ht…

Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

Qt:QMetaObject::connectSlotsByName实现信号槽自动关联

简介 在Qt中&#xff0c;QMetaObject::connectSlotsByName 是一个便利的方法&#xff0c;它可以根据对象的对象名&#xff08;objectName&#xff09;自动将信号和槽连接起来。但是&#xff0c;要使用这个方法&#xff0c;必须确保&#xff1a; 1 控件&#xff08;如按钮&…

数据挖掘之认识数据

在数据挖掘过程中&#xff0c;数据的认识是非常重要的一步&#xff0c;它为后续的数据分析、建模、特征选择等工作奠定基础。以鸢尾花数据集&#xff08;Iris Dataset&#xff09;数据集之鸢尾花数据集&#xff08;Iris Dataset&#xff09;-CSDN博客为例&#xff0c;下面将介绍…

useContext Hook 的使用及规范

首先 useContext 是什么&#xff1f; useContext 是 React 提供的一个 Hook&#xff0c;允许函数组件订阅 React 的 Context。 有什么用&#xff1f; 它使得你可以在不使用 Consumer 组件的情况下访问 Context 的值。通过 useContext&#xff0c;你可以轻松地在多层级组件之间…

MacOS 命令行详解使用教程

本章讲述MacOs命令行详解的使用教程&#xff0c;感谢大家观看。 本人博客:如烟花般绚烂却又稍纵即逝的主页 MacOs命令行前言&#xff1a; 在 macOS 上,Terminal&#xff08;终端) 是一个功能强大的工具&#xff0c;它允许用户通过命令行直接与系统交互。本教程将详细介绍 macOS…

Mac上详细配置java开发环境和软件(更新中)

文章目录 概要JDK的配置JDK下载安装配置JDK环境变量文件 Idea的安装Mysql安装和配置Navicat Premium16.1安装安装Vscode安装和配置Maven配置本地仓库配置阿里云私服Idea集成Maven Cpolar快速入门 概要 这里使用的是M3型片 14.6版本的Mac 用到的资源放在网盘 链接: https://pan…

Neo4j 图数据库安装与操作指南(以mac为例)

目录 一、安装前提条件 1.1 Java环境 1.2 Homebrew&#xff08;可选&#xff09; 二、下载并安装Neo4j 2.1 从官方网站下载 2.1.1 访问Neo4j的官方网站 2.1.2 使用Homebrew安装 三、配置Neo4j 3.1 设置环境变量(可选) 3.2 打开配置文件(bash_profile) 3.2.1 打开终端…

【数据结构练习题】链表与LinkedList

顺序表与链表LinkedList 选择题链表面试题1. 删除链表中等于给定值 val 的所有节点。2. 反转一个单链表。3. 给定一个带有头结点 head 的非空单链表&#xff0c;返回链表的中间结点。如果有两个中间结点&#xff0c;则返回第二个中间结点。4. 输入一个链表&#xff0c;输出该链…

图书借阅管理系统|SpringBoot|HTML|web网站|Java【源码+数据库文件+包部署成功+答疑解惑问到会为止】

代码包运行启动成功&#xff01;不管你有没有运行环境&#xff0c;哪怕你是刚买的新电脑&#xff0c;也包启动运行成功&#xff01;有不懂的地方随便问&#xff01;问到会为止&#xff01; 【功能介绍】 该系统有两种角色&#xff1a; 管理员&#xff0c;读者。 1.管理员可以添…

Qt Quick:CheckBox 复选框

复选框不止选中和未选中2种状态哦&#xff0c;它还有1种部分选中的状态。这3种状态都是Qt自带的&#xff0c;如果想让复选框有部分选中这个状态&#xff0c;需要将三态属性&#xff08;tristate&#xff09;设为true。 未选中的状态值为0&#xff0c;部分选中是1&#xff0c;选…

【ue5学习笔记2】在场景放入一个物体的蓝图输入事件无效?

在场景放入一个物体的蓝图输入事件无效&#xff0c;那是因为你不知道gameMode这个东西这是一个用于设定游戏股则的东西&#xff0c; 就好比你的控制对象&#xff0c;你输入无效是没有指定你当前关卡中指定的控制对象是它。操作方法如下&#xff1a; 1.创建一个gameMode蓝图类并…

pro文件转换为CMakeLists.txt文件,QT官方工具使用教程

某些情况需要使用cmake&#xff0c;如果手动将QT的pro文件转换成CMakeLists.txt&#xff0c;简短一点的pro还好&#xff0c;如果是比较复杂的pro&#xff0c;手动转换的时候需要长时间的debug&#xff0c;本人深有感受。 工具介绍&#xff1a; qmake2cmake工具创建一个CMakeL…

Python读取Excel批量写入到PPT生成词卡

一、问题的提出 有网友想把Excel表中的三列数据&#xff0c;分别是&#xff1a;单词、音标和释义分别写入到PPT当中&#xff0c;每一张PPT写一个单词的内容。这种批量操作是python的强项&#xff0c;尤其是在办公领域&#xff0c;它能较好地解放双手&#xff0c;读取Excel表后…

【快速上手】linux环境下Neo4j的安装与使用

一、neo4j简介 neo4j是一个非关系型图形数据库&#xff0c;非常适合处理具有复杂关系的数据集 存储方式&#xff1a;图形化存储 特点&#xff1a;将结构化数据存储在图上而不是表&#xff08;比如&#xff1a;MySQL数据库存储在表中&#xff09;中 neo4j也可以看作是一个高…