Spring中AOP学习笔记
AOP
- 描述(摘抄百度百科)
- AOP开发中的相关操作术语
- 实例(xml方式)
- 通知的类型
- 切入点表达式的写法:
- 实例(注解方式)
描述(摘抄百度百科)
AOP(面向切面编程):Aspect Oriented Programming的缩写。意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP开发中的相关操作术语
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。其实就是类里面可以被增强的方法,这些方法称为连接点。
Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。比如实际开发中只对saveAccount()方法增强,该方法就是切入点。
Advice(通知/增强):增强的逻辑,称为增强或通知
Aspect(切面):把增强应用到切入点上面的过程称为切面。
Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。
Target(目标对象):代理的目标对象。
Proxy(代理):代理对象
Weaving(织入):将通知应用到目标的过程。例如:将日志记录应用到saveAccount()方法上面。
下图更直观:
实例(xml方式)
创建一个meavn工程,pom文件中添加如下依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
AccountService 接口:
public interface AccountService {
/***
* 保存账户
*/
void saveAccount();
/***
* 更新账户
*/
void updateAccount(Integer i);
/***
* 删除账户
*/
void deleteAccount(Integer i);
}
AccountServiceImpl实现类:
public class AccountServiceImpl implements AccountService {
public void saveAccount() {
System.out.println("保存用户成功.....");
}
public void updateAccount(Integer i) {
System.out.println("更新用户成功.....");
}
public void deleteAccount(Integer i) {
System.out.println("删除用户成功.....");
}
}
再编写一个增强的类Logger:
public class Logger {
/***
* @Description: 用于打印日志
* @Date: 2021/2/9
*/
public void Printlog(){
System.out.println("输出打印日志.....");
}
}
bean.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--配置service-->
<bean id="accountService" class="com.zy.aop.service.AccountServiceImpl"></bean> <!--配置切面logger类-->
<bean id="logger" class="com.zy.aop.logger.Logger"></bean> <!--配置Aop-->
<aop:config>
<!--配置切入点表达式-->
<aop:pointcut id="log" expression="execution(public void com.zy.aop.service.AccountServiceImpl.saveAccount())"/>
<!--配置切面-->
<aop:aspect id="" ref="logger">
<!--前置通知:在切入点方法执行前执行-->
<aop:before method="Printlog" pointcut-ref="log"></aop:before>
</aop:aspect>
</aop:config>
</beans>
测试代码:
public class TestAop {
@Test
public void TestSaveAccount(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = (AccountService) context.getBean("accountService");
accountService.saveAccount();
accountService.updateAccount(1);
Integer i = 10;
}
}
运行结果:
标签说明:
| 标签 | 说明 |
|---|---|
| aop:config | 该标签声明aop配置开始 |
| aop:pointcut | 用于配置切入点表达式。就是指定对哪些类的哪些方法进行增强。属性:expression:用于定义切入点表达式。id:用于给切入点表达式提供一个唯一标识 |
| aop:aspect | 用于配置切面。属性:id:给切面提供一个唯一标识。ref:引用配置好的通知类 bean 的 id |
通知的类型
| 通知类型 | 标签 |
|---|---|
| 前置通知 | <aop:before method="" pointcut-ref=""></aop:before> |
| 后置通知 | <aop:after-returning method="" pointcut-ref=""></aop:after-returning> |
| 异常通知 | <aop:after-throwing method=""></aop:after-throwing> |
| 最终通知 | <aop:after method="" pointcut-ref=""></aop:after> |
| 环绕通知 | <aop:around method="" pointcut-ref=""></aop:around> |
每一个标签中都有这三个属性method:指定通知中方法的名称。pointct:定义切入点表达式pointcut-ref:指定切入点表达式的引用。
前置通知:
<aop:config>
<aop:pointcut id="log" expression="execution(* com.zy.aop.service.AccountServiceImpl.saveAccount())"/>
<aop:aspect id="" ref="logger">
<!--前置通知:在切入点方法执行前执行-->
<aop:before method="Printlog" pointcut-ref="log"></aop:before>
</aop:aspect>
</aop:config>
后置通知:
<aop:config>
<aop:pointcut id="log" expression="execution(* com.zy.aop.service.AccountServiceImpl.saveAccount())"/>
<aop:aspect id="" ref="logger">
<!--后置通知:在切入点方法执行后执行-->
<aop:after-returning method="Printlog" pointcut-ref="log"></aop:after-returning>
</aop:aspect>
</aop:config>
异常通知:
<aop:config>
<aop:pointcut id="log" expression="execution(* com.zy.aop.service.AccountServiceImpl.saveAccount())"/>
<aop:aspect id="" ref="logger">
<!--异常通知:程序出现异常的时候,进行的操作-->
<aop:after-throwing method="Printlog" pointcut-ref="log"></aop:after-throwing>
</aop:aspect>
</aop:config>
最终通知:
<aop:config>
<aop:pointcut id="log" expression="execution(* com.zy.aop.service.AccountServiceImpl.saveAccount())"/>
<aop:aspect id="" ref="logger">
<!--最终通知:在切入点方法执行后执行,无论方法是否正常执行都会在后面执行-->
<aop:after method="Printlog" pointcut-ref="log"></aop:after>
</aop:aspect>
</aop:config>
环绕通知:
<aop:config>
<aop:pointcut id="log" expression="execution(* com.zy.aop.service.AccountServiceImpl.saveAccount())"/>
<aop:aspect id="" ref="logger">
<!--环绕通知-->
<aop:around method="Printlog2" pointcut-ref="log"></aop:around>
</aop:aspect>
</aop:config>
我们要修改一下增强的类Logger中的方法:
public class Logger {
/***
* @Description: 用于打印日志
* @Date: 2021/2/9
*/
public void Printlog() {
System.out.println("输出打印日志.....");
}
public Object Printlog2(ProceedingJoinPoint pro) {
Object proceed = null;
Object[] args = pro.getArgs();//得到方法实行所需参数
try {
//在这之前是前置通知
proceed = pro.proceed(args);//调用业务层方法
//在这之后是后置通知
return proceed;
} catch (Throwable t) {
//在这是异常通知
} finally {
//在这是最终通知
}
return proceed;
}
}
切入点表达式的写法:
表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))
写法说明:
全匹配方式:public void com.zy.aop.service.AccountServiceImpl.saveAccount(参数类型)
访问修饰符可以省略: void com.zy.aop.service.AccountServiceImpl.saveAccount(参数类型)
返回值可以使用号,表示任意返回值: com.zy.aop.service.AccountServiceImpl.saveAccount(参数类型),具体可以百度在这我就不写了。
通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类。
execution(* com.zy.aop.service..(…))
Spring中AOP学习笔记的更多相关文章
- spring 中bean学习笔记
spring 中bean 一.bean的定义和应用 1. bean 形象上类似于getXX()和setXX()的一种. 2. 由于java是面向对象的,类的方法和属性在使用中需要实例化. 3. 规律: ...
- Spring中AOP原理,源码学习笔记
一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...
- Spring入门IOC和AOP学习笔记
Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容 ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
- 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)
一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...
- Spring 源码学习笔记11——Spring事务
Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- Spring中AOP简介与切面编程的使用
Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...
- spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)
绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...
随机推荐
- kill 指令的执行原理
kill 指令有两种写法 " kill query + 线程 id "." kill connection(可缺省) + 线程 id ".分别表示关闭指定线程正 ...
- kubernets之pv以及pvc
一 持久卷以及持久卷声明的由来 由于不管是哪种卷,开发者都需要提前预知kubernets集群里面的存储类型,这样就在一定程度上违背了kubernets集群的设计理念,kubernets的设计理念是在由 ...
- 开发进阶:Dotnet Core多路径异步终止
今天用一个简单例子说说异步的多路径终止.我尽可能写得容易理解吧,但今天的内容需要有一定的编程能力. 今天这个话题,来自于最近对gRPC的一些技术研究. 话题本身跟gRPC没有太大关系.应用中,我用 ...
- Docker Hub公共镜像仓库的使用
创建账号并登陆这里是登陆入口 登陆账号 登陆进入之后里面目前仓库,现在去创建一个 下面我选的是公共仓库,别人也可以访问到 在服务器上登陆进来,进行上传镜像到仓库 [root@docker ~]# do ...
- RocketMQ在linx安装及其有关问题解决
Linx安装和使用: rocketmq官网:http://rocketmq.apache.org/ 首先安装JDK(推荐使用JDK1.8),并配置环境变量 下载rocketmq压碎包并解压到指定目录 ...
- Java异常处理场景中不同位置的返回值详细解析
Java 异常处理中的返回值在不同位置不同场景下是有一些差别的,这里需要格外注意 具体分以下两种场景: 1 finally语句块没有return语句,即当代码执行到try或者catch语句块中的ret ...
- django ajax应用
ajax: 什么是ajax,有什么作用: 以前我们在页面向后台提交数据的时候都是使用from表单,这样的提交会在提交的时候将整个页面全部刷新,如果你在填写表单的时候提交之后发现某个数据不对,但是你已提 ...
- Linux安装redis报错:jemalloc/jemalloc.h: No such file or directory踩坑
报错内容: 针对这个错误,我们可以在README.md 文件中看到解释: --------- Selecting a non-default memory allocator when buildin ...
- HA工作机制及namenode向QJM写数据流程
HA工作机制 (配置HA高可用传送门:https://www.cnblogs.com/zhqin/p/11904317.html) HA:高可用(7*24小时不中断服务) 主要的HA是针对集群的mas ...
- Spring Boot使用MongoDB GridFS进行文件的操作
1. GridFS简介 GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片.音频.视频等),但是它是存储在MonoDB的集合中. GridFS 会将文件对象分割成多个的ch ...