当前位置: 首页 > article >正文

一文搞懂AOP 通俗易懂

文章目录

  • 前言
  • 一、AOP是什么?
  • 二、使用步骤
    • 1.引入Aspect依赖
    • 2.编写代码
      • 2.1 使用注解+AOP方式实现切面
      • 2.2 使用execution+AOP方式实现切面
    • 3. 写在最后
  • 总结
    • 如果您有Java方面的问题(不局限于此文章的问题),欢迎公众号提出您的问题,我将在第一时间为您解答~


前言

提示:这里可以添加本文要记录的大概内容:

Spring有两大核心,AOP和IOC,本文着重讲解AOP。


一、AOP是什么?

AOP是Aspect Oriented Programming,即面向切面编程。
什么是面向切面呢?
要理解AOP的概念,我们先用OOP举例,OOP大家都知道,面向对象编程。比如一个业务组件BookService,它有几个业务方法:

  • createBook:添加新的Book;
  • updateBook:修改Book;
  • deleteBook:删除Book。

对每个业务方法,例如,createBook(),除了业务逻辑,还需要安全检查、日志记录和事务处理,它的代码像这样:

public class BookService {public void createBook(Book book) {securityCheck();Transaction tx = startTransaction();try {// 核心业务逻辑tx.commit();} catch (RuntimeException e) {tx.rollback();throw e;}log("created book: " + book);}
}

然后你就会发现增删改的方法都需要做这些判断,很繁琐,解决办法有两种:
一种可行的方式是使用Proxy模式,将某个功能,例如,权限检查,放入Proxy中,但是这种方式的缺点是比较麻烦,必须先抽取接口,然后,针对每个方法实现Proxy。
所以第二种方法AOP应运而生了。
AOP技术看上去比较神秘,但实际上,它本质就是一个动态代理,让我们把一些常用功能如权限检查、日志、事务等,从每个业务方法中剥离出来。

二、使用步骤

1.引入Aspect依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version>
</dependency>

2.编写代码

这里我先模拟一个简单的场景,用最简洁的代码教会大家。
假设我们进行了一条数据的更新(update),需要记录日志,如果报错需要抛出异常,这时候我们可以用到前置通知(其实是在插入成功后,后置通知)和异常通知

2.1 使用注解+AOP方式实现切面

首先我们定义一个注解类AdminOnly

@Retention(RetentionPolicy.RUNTIME)  //运行期
@Target(ElementType.METHOD) //作用在方法上
public @interface AdminOnly {
}

然后就可以编写切面类了,

@Aspect
@Component
public class CheckUserAspect {//注解方式,方法其实是个空壳//此时注解就跟此方法绑定了,后续使用注解的方法都会被带上切面所标识的方法@Pointcut("@annotation(com.tao.aop.annotation.AdminOnly)")private void checkAdmin(){}@Before("checkAdmin()") // 前置通知,checkAdmin()跟拦截器进行绑定private void Before(){System.out.println("前置通知...日志记录");}@AfterThrowing( value = "checkAdmin()",throwing = "e")  //异常通知 checkAdmin()跟拦截器进行绑定private void afterThrowing(Throwable e) {System.out.println("报错后通知...");System.out.println(e.getMessage());}
}

UserService类

@Service
public class UserService {@AdminOnly  //注:要想被切面的方法需要加上这个注解public void update() {System.out.println("进行了update操作...");}
}

此时使用测试类,调用UserService中的update方法,你会发现结果是:

前置通知…权限校验
进行了update操作…

已经加上了AOP操作。接下来讲解通过execution来划定范围

2.2 使用execution+AOP方式实现切面

切面类 CheckUserAspect ,看得出,我把service包下的所有类,所有方法都拦截了

@Aspect
@Component
public class CheckUserAspect {//表达式方式// execution 代表的意思/** 第一个 * 号代表返回值为任意类型*第二位代表 包名*第三位 .* 代表任意类*第四位 .*(..) 表示任何方法名的任何参数** */@Pointcut("execution(* com.tao.aop.service.*.*(..))")private void checkAdmin(){//此方法是空壳}@Before("checkAdmin()") // 前置通知,checkAdmin()跟拦截器进行绑定private void Before(){System.out.println("前置通知...日志记录");}@AfterThrowing( value = "checkAdmin()",throwing = "e")  //异常通知 checkAdmin()跟拦截器进行绑定private void afterThrowing(Throwable e) {System.out.println("报错后通知...");System.out.println(e.getMessage());}
}

UserService1类

@Service
public class UserService1 {public void update() throws Exception {System.out.println("进行了update操作...");throw new  Exception("自造异常");}
}

前置通知以及我自己模拟的异常通知都触发了,结果如下:

前置通知…权限校验
进行了update操作…
报错后通知…
自造异常

3. 写在最后

还有一些拦截通知类型,我就不一一举例,感兴趣的同学可以关注公众号,探讨及提问。

@Before:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;@After:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;@AfterReturning:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;@AfterThrowing:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;@Around:能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码,可以说是包含了上面所有功能。

总结

总的来说,AOP已经是开发必备或者说面试必问,老生常谈的问题了,如果想要详细源码或者不懂的地方关注公众号,回复AOP实例源码 即可获取全部源码

如果您有Java方面的问题(不局限于此文章的问题),欢迎公众号提出您的问题,我将在第一时间为您解答~

在这里插入图片描述

有惊喜哟~
在这里插入图片描述

http://www.lryc.cn/news/2417720.html

相关文章:

  • NTFS(微软专用文件系统)
  • vault-服务器密码/证书管理工具
  • Content-type的几种常见类型及php://input的使用
  • STM32之RCC(1)
  • ASP是什么?
  • 爬虫解析——Xpath的安装及使用(五)
  • OpenCore 黑苹果安装教程
  • sonar小白式入门
  • 深度学习简介与MLP多层感知机
  • Linux命令200例:find用来查找文件和目录,不可错过的15个例子
  • AcWing 算法基础课笔记 1.基础算法
  • thmeleaf模板引擎使用总结
  • 这篇文章带你认识一款优秀国产云原生数据库 ,它就是《阿里 PolarDB》数据库
  • MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password: YES)无法打开的解决方法
  • HINT的30个用法
  • ARP协议详解:了解数据包转发与映射机制背后的原理
  • Source Insight 4.0使用和解决问题
  • 神经网络模型训练中的相关概念:Epoch,Batch,Batch size,Iteration
  • Yandex企业邮箱注册
  • nsfw什么颜色_“ NSFW”是什么意思,以及如何使用它?
  • 公开密钥加密算法RSA的理论概述
  • Java面试题及答案整理汇总
  • Rsync教程--linux服务器文件实时同步
  • 前端关于单点登录的知识
  • ssh安装与配置(详解版)
  • zlib 库的使用
  • Restful风格详解
  • 一文带你了解SOA接口测试
  • stack overflow异常分析及解决办法
  • Hdfs(五)DataNode