兴国网站建设,如何在自己网站做解析api,建设企业网站的原因,推广比较好的网站文章目录 前言一、什么是 AOP ?二、为什么要使用 AOP ?三、 AOP 的组成四、Spring AOP 的实现1, 添加依赖2, 定义切面3, 定义切点4, 定义通知5, 创建连接点 总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: #x1f4d5; JavaSE基础: 基础语法… 文章目录 前言一、什么是 AOP ?二、为什么要使用 AOP ?三、 AOP 的组成四、Spring AOP 的实现1, 添加依赖2, 定义切面3, 定义切点4, 定义通知5, 创建连接点 总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等 JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新) 提示是正在努力进步的小菜鸟一只如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说直接上干货 一、什么是 AOP ?
AOPAspect Oriented Programming面向切面编程, 这是一种思想, 是对某一类事情的集中处理, 其核心思想是将那些与业务逻辑无关, 但是被多处业务逻辑模块共享的代码比如判断用户登录, 日志管理, 权限检查, 事务管理等抽取出来集中处理, 这样, 开发者可以将更多的精力放在处理核心业务逻辑上
Spring AOP 是一个框架, 对 AOP 思想的一种实现 二、为什么要使用 AOP ?
基本上每一个 Web 项目(会故意一下你使用过的网站或 APP ), 都有用户登录功能, 对于一个网站来说, 除了登录页和注册页, 基本上每个页面都有用户登录之后才能进行的操作, 那么这些页面都要在 controller 层进行校验用户登录之后才能编写业务代码
然而当你的功能越来越多, 那么你要写的登录验证也越来越多, 但这些方法又是相同的这么多的方法就会代码修改和维护的成本, 对于这种功能统一的需求, 更简单方便的方式就是 AOP AOP 可以扩充多个对象的某个能力, 所以 AOP 可以说是 OOPObject Oriented Programming, 面向对象编程的补充和完善 三、 AOP 的组成
切面(通常是一个类) 指的是某一类事情的具体内容, 比如用户登录校验就是一个切面, 日志统一记录也是一个切面, 通常切面是一个类 切面是包含了通知、切点和切面的类, 相当于 AOP 实现的某个功能的集合 可以把切面看作是一个模块, 它的目标是完成一些特定的工作, 这些工作通过通知实现, 而切点则确定了这些工作应当在何处执行。 切点 (通常是一个方法) 切点用来定义 AOP 拦截的规则的(使用AspectJ pointcut expression language 来描述), 通常是类中的一个方法, 该方法不需要实现, 只是一个标识, 后面用代码展示 所谓的拦截规则其实就是你的 通知 应该在何处执行 你可以将切点视为一个包含了多个连接点的集合, 这个集合中的每个元素即每个连接点都将应用通知执行通知中的方法 连接点(通常也是方法) 所有可能触发切点的点就称之为连接点 连接点是程序执行的某个特定位置, 如类的某个方法调用前、调用后、方法捕获到异常后等, 在Spring AOP中, 一个连接点总是代表一个方法的执行 通知 (方法具体实现代码) 切面也是有目标的 ——它要必须完成什么工作? 在 AOP 术语中, 切面的工作被称之为通知 Spring 切面类中可以在方法上使用以下注解会设置方法为通知方法在满足条件后会通知本方法进行调用 前置通知 Before这个注解标注的方法会在目标方法实际要执行的方法被调用前执行后置通知 After这个注解标注的方法会在目标方法完成后执行, 无论目标方法是否成功完成环绕通知 Around这个注解标注的方法会在目标方法调用前后都执行, 可以自行决定何时执行目标方法异常通知 AfterThrowing这个注解标注的方法会在目标方法抛出异常后执行方法返回通知 AfterReturning这个注解标注的方法会在目标方法成功返回后执行 四、Spring AOP 的实现
我们用 Spring AOP 来实现⼀下 AOP 的功能, 完成的目标是拦截所有 UserController 里的方法, 每次调用 UserController 中任意方法时(拦截到), 都执行相应的通知事件 1, 添加依赖
把下面这段代码拷贝到 pom.xml 中
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactIdversion2.7.11/version
/dependency2, 定义切面
Aspect // 定义该类为切面
Component // 随框架加载而加载
public class UserAspect {}3, 定义切点
Aspect // 定义该类为切面
Component // 随框架加载而加载
public class UserAspect {// 切点(下面这段字符串就是用来定义拦截规则的)Pointcut(execution(* com.example.demo.controller.UserController.*(..)))public void pointCut(){}
}pointcut() 为空方法, 它不需要有方法体, 此方法名就是起到⼀个 “标识/关联” 的作用, 标识 通知方法 具体指的是哪个切点因为切点可能有很多个
Aspect 语法中的通配符
* : 表示匹配任意的内容, 用在返回值, 包名, 类名, 方法都可以使用..: 匹配任意字符可以使用在方法参数上, 如果用在类上需要配合 * 一起使用 : 表示匹配指定类及其它底下的所有子类, 比如 com.UserController 表示匹配 com.UserController 及其所有子类
AspectJ 语法(Spring AOP 切点的匹配方法)
切点表达式由切点函数组成, 其中 execution() 是最常用的切点函数, 用来匹配方法, 语法为 execution(修饰符返回类型包.类.⽅法(参数)异常)
修饰符一般省略public公共方法, *任意返回类型不能省略void, String, int, *任意包com.demo(固定包), com.*( com 包下所有), com.demo..( com.demo 包下所有子包含自己)类Test (固定类)Test* (以 Test 开头)*Test(以 Test 结尾)*(任意)方法名不能省略addUser(固定方法), add*(以 add 开头), *add(以 add 结尾), *(任意)参数(), (int), (int,String), (…)任意参数异常可省略, 一般不写
4, 定义通知
注意看, 在下面各种通知方法的注解中, 参数为 “pointCut()” , 这就和上面写的切点方法关联上了 配合 System.currentTimeMillis() 观察这些通知方法具体的执行时机 Aspect // 定义该类为切面
Component // 随框架加载而加载
public class UserAspect {// 切点Pointcut(execution(* com.example.demo.controller.UserController.*(..)))public void pointCut(){}// 前置通知Before(pointCut())public void doBefore(){System.out.println(执行前置通知 System.currentTimeMillis());}// 后置通知After(pointCut())public void doAfter(){System.out.println(执行 后置通知 System.currentTimeMillis());}// return 之前通知AfterReturning(pointCut())public void doAfterReturning(){System.out.println(执⾏ 返回后通知 System.currentTimeMillis());}// 抛出异常之前通知AfterThrowing(pointCut())public void doAfterThrowing() {System.out.println(执⾏ 异常后通知 System.currentTimeMillis());}// 环绕通知Around(pointCut()) // 参数是拿到目标方法的执行对象public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println(环绕通知 执行开始 System.currentTimeMillis());Object object null;object joinPoint.proceed();// 执行目标方法System.out.println(环绕通知 执行结束 System.currentTimeMillis());return object;}
}环绕通知带有参数, 参数 joinPoint 的意义就是拿到目标方法(要执行的方法就是目标方法, 比如下面的 sayHi() )的执行对象, 也就是 UserController 中的所有方法的执行对象. 用这个对象调用 proceed() 就是执行 UserController 中的所有方法. 环绕通知的返回值和目标方法的方法类型无关, 它只决定框架能否继续执行后续流程 5, 创建连接点
在 Controller 类下面定义
RestController
RequestMapping(/user)
public class UserController {RequestMapping(/sayhi)public String sayHi(){System.out.println(hi~ System.currentTimeMillis());return hi~ System.currentTimeMillis();}
}运行项目, 访问 http://127.0.0.1:8080/user/sayhi 环绕通知的前置方法在最前面执行, 环绕通知的后置方法在最后执行 因为切点方法中使用了 AspectJ 语法规定了拦截路径, 所以 Controller 类下面的这个 sayHi() 才会被拦截, 执行这些通知方法 总结
以上就是本篇的所有内容了, 如果本篇对你有帮助请点赞收藏支持一下小手一抖就是对作者莫大的鼓励啦~ 上山总比下山辛苦 下篇文章见