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

Java SpringAOP --- AOP的使用,AOP的源码

文章目录

  • SpringAOP
    • 引入AOP依赖
    • AOP的使用
    • AOP的详解
      • AOP概念(理解)
        • 通知类型
        • 切点
        • 切面的优先级
        • 切点表达式
        • 注解匹配
    • Spring 原理
      • 代理模式
      • 静态代理
      • 动态代理
    • AOP的源码(了解)

SpringAOP

Spring两大核心思想:IoC和AOP(AOP是面试频率最高的)

  1. AOP就是对某一类特定问题的集中处理(AOP是一种思想),AOP是面向切面编程,OOP是面向对象编程
    在这里插入图片描述

引入AOP依赖

  1. 在pom.xml文件中添加配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

AOP的使用

  1. 实现一个AOP的实例:打印所有接口的耗时时间,这就是对所有方法的统一处理
    在这里插入图片描述
@Slf4j
@Aspect
@Component
public class TimeAspect {// ProceedingJoinPoint表示的作用目标方法是什么// 针对所有的方法都生效使用的注解@Around("execution(* com.example.demo.controller.*.*(..))")public Object timeCost(ProceedingJoinPoint joinPoint) throws Throwable {long start = System.currentTimeMillis();// 让作用的目标方法执行Object result = joinPoint.proceed();long end = System.currentTimeMillis();log.info(joinPoint.getSignature() + "消耗的时间: " + (end - start) + "ms");return result;}
}

在这里插入图片描述
在这里插入图片描述

AOP的详解

在这里插入图片描述

AOP概念(理解)

  1. 切点:一组规则,通过表达式来描述,告诉程序对哪些方法来进行功能增强
    切点就是要作用的路径
    切点表达式:
    在这里插入图片描述

  2. 连接点:切面要作用的方法,目标方法,切点要描述的方法
    连接点就是作用的具体方法
    在这里插入图片描述

  3. 通知:具体的逻辑,要做什么处理(可以理解为代码的逻辑)

  4. 切面:切点 + 通知

举个例子:
切点就是某个班的学生
连接点就是某个具体的学生,张三,李四
123班学生今天要进行javaee的考试,要进行的考试就是通知

AOP是对一类事情的集中处理

在这里插入图片描述

通知类型

在这里插入图片描述

  1. 接口响应正常
    在这里插入图片描述
    都是一圈一圈执行的,Around是先执行外圈,再执行内圈的,就和一个圆环是类似的

执行顺序:
在这里插入图片描述

  1. 接口响应异常
    在这里插入图片描述

执行顺序:
在这里插入图片描述

// 主要代码@Slf4j
@Aspect
@Component
public class AspectDemo {// 第一个.*是所有的类都生效,第二个.*是所有的方法都生效@Before("execution(* com.example.aopdemo.demos.controller.*.*(..))")public void doBefore(){log.info("执行AspectDemo before...");}@After("execution(* com.example.aopdemo.demos.controller.*.*(..))")public void doAfter(){log.info("执行AspectDemo after...");}@AfterReturning("execution(* com.example.aopdemo.demos.controller.*.*(..))")public void doAfterReturning(){log.info("执行AspectDemo afterReturning...");}@AfterThrowing("execution(* com.example.aopdemo.demos.controller.*.*(..))")public void doAfterThrowing(){log.info("执行AspectDemo afterThrowing...");}@Around("execution(* com.example.aopdemo.demos.controller.*.*(..))")// Around必须返回结果public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {log.info("执行AspectDemo around 前...");// 调用目标方法,执行结果Object result = joinPoint.proceed();log.info("执行AspectDemo around 后...");return result;}
}// 测试代码
@RestController
public class HelloController {@RequestMapping("/helloo")public String hello(){return "hello";}@RequestMapping("/t1")public String t1(){int a = 10 / 0;return "t1";}
}
切点

每个方法前都要写这个切点,是不是太麻烦了??
有没有更简单的,可以把这行提取出来呢?
在这里插入图片描述

  1. 定义一个切点叫做pt,这个名字是可以任意取的
    在这里插入图片描述
  2. 定义的这个切点能否在其他切面(类)中使用呢??
    这个切点可以再其他类中使用的,如果其他类需要使用,需要把切点声明为public,使用时,类的全限定名称(包 + 类名) + 切点名称

切点名称为public修饰的
在这里插入图片描述

在其他类中使用
在这里插入图片描述
3. 当有多个切面时,切面的执行顺序是按名称进行排序的
优先级高:先执行before,后执行After
在这里插入图片描述

切面的优先级
  1. 如果开发的时候,要算切面的执行顺序是怎么样的,实在是太麻烦了??
    使用@Order来定义切面的优先级
    在这里插入图片描述
    从图中可以看出,先执行优先级高的before方法,再执行优先级低的before方法,再执行目标方法,再执行优先级低的after方法,最后执行优先级高的after方法

在这里插入图片描述

切点表达式
  1. 切点表达式的类型以及其写法:
execution(<访问修饰符> <返回类型> <包名.类名.⽅法(⽅法参数)> <异常>)

在这里插入图片描述
通配符的作用:
在这里插入图片描述
下面这些了解就可以了

TestController 下的 public修饰, 返回类型为String 方法名为t1, 无参方法

execution(public String com.example.demo.controller.TestController.t1())

省略访问修饰符

execution(String com.example.demo.controller.TestController.t1())

匹配所有返回类型

execution(* com.example.demo.controller.TestController.t1())

匹配TestController 下的所有无参方法

execution(* com.example.demo.controller.TestController.*())

匹配TestController 下的所有方法

execution(* com.example.demo.controller.TestController.*(..))

匹配controller包下所有的类的所有方法

execution(* com.example.demo.controller.*.*(..))

匹配所有包下面的TestController

execution(* com..TestController.*(..))

匹配com.example.demo包下, 子孙包下的所有类的所有方法

execution(* com.example.demo..*(..))
注解匹配

为了解决要包含这个类的所有方法,所有的类,这种就太宽泛了,为了指定特定的路径或者是方法使用注解匹配

  1. 编写自定义的注解
  2. 使用@annotation表达式来描述切点
  3. 在连接点的方法上添加自定义注解

annotation就是注解的意思
自定义注解作用就是指定哪些方法使用,内部的一些内容
在这里插入图片描述

自定义一个注解:

// METHOD表示只能作用到方法上
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface MyAspect {}

(1) @Tatget作用的范围
在这里插入图片描述
(2) 注解的生命周期
在这里插入图片描述
常见的面试题:
在这里插入图片描述

Spring 原理

  1. AOP常见的实现方式:
    aspectJ自己也有实现AOP的方式,但是我们只用学Spring实现AOP的方式,虽然是Spring用了aspectJ的名字,但是也是自己实现的
    在这里插入图片描述

代理模式

  1. Spring AOP原理是基于代理来实现的
    代理模式:有静态代理和动态代理

什么是代理模式??
举个例子:
租户直接找房东就是没有代理模式的,
租户通过中介找房东就是有代理模式的
在这里插入图片描述

静态代理

  1. 静态代理:在程序运行前,代理对象就已经对目标对象进行了步骤的预执行代码

举个例子:
在这里插入图片描述

// 接口
package com.example.aopdemo.demos.proxy;// 要实现的出租房子的接口
public interface HouseSubject{// 出租房子void rentHouse();// 卖房子void saleHouse();
}package com.example.aopdemo.demos.proxy;// 目标对象
// 房东
public class RealHouseSubject implements HouseSubject{@Overridepublic void rentHouse() {System.out.println("我是房东,我要出租房子!");}@Overridepublic void saleHouse() {System.out.println("我是房东,我要卖房子!");}
}// 代理对象
package com.example.aopdemo.demos.proxy;// 中介是没有房子的,最后还是需要房东来做这个工作的
public class HouseProxy implements HouseSubject{// 目标对象,被代理对象private HouseSubject houseSubject;public HouseProxy(HouseSubject houseSubject) {this.houseSubject = houseSubject;}@Overridepublic void rentHouse() {System.out.println("开始进行代理");houseSubject.rentHouse();System.out.println("结束代理");}@Overridepublic void saleHouse() {System.out.println("开始进行代理");houseSubject.saleHouse();System.out.println("结束代理");}
}// 测试类
package com.example.aopdemo.demos.proxy;public class Main {public static void main(String[] args) {// 目标对象// 静态代理:在代理的时候,就知道了是哪个对象HouseSubject subject = new RealHouseSubject();HouseSubject proxy = new HouseProxy(subject);proxy.rentHouse();}
}
  1. 代理模式的主要角色:
    proxy就是代理的意思,以后在读源码的时候看到这个就翻译为代理
    在这里插入图片描述

动态代理

  1. 动态代理常见的实现方式:
    (1) JDK
    (2) CGlib:这是第三方提供的

(1) JDK
动态代理和静态代理只需要理解就行,不需要自己写代码
JDK只能代理接口,不能代理类,这是规定
在这里插入图片描述

(2) CGLIB 动态代理实现

添加依赖:

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>

通过反射进行实现:
在这里插入图片描述
代理的目的:对目标对象进行功能的增强

CGLIB 既可以代理类,又可以代理接口

AOP的源码(了解)

容易考面试题:
SpringAOP 的实现方式:
(1) execution
(2) 自定义注解

  1. Spring AOP是怎么实现的
    是基于动态代理实现的

  2. 动态代理是怎么实现的
    Spring 动态代理是基于JDK和CGlib实现的

  3. Spring 使用的是哪个?
    两个都有

  4. 什么时候使用JDK,什么时候使用CGLIB??
    那么代理接口的时候,什么时候使用JDK,什么时候使用CGLIB??
    在SpringBoot 2.X之前,类是使用cglib代理,接口是使用jdk代理
    在这里插入图片描述

  5. JDK 和 CGLib有什么区别??
    代理类,只能使用CGlib
    代理接口,可以使用JDK,也可以使用CGLIB

在这里插入图片描述
在这里插入图片描述
设计模式考的是思想,而不是代码
最容易问的模式:
策略模式和模版模式的区别,
代理模式和适配器模式的区别,
最有可能写代码的是单例模式

在这里插入图片描述

http://www.dtcms.com/a/524199.html

相关文章:

  • 阿里云渠道商:如何设置阿里云的安全组规则?
  • 网站设计速成如何让百度快速收录网站文章
  • 北京平台网站建设多少钱学院网站建设的特色
  • 外贸soho建站多少钱山东省住房和城乡建设厅官方网站
  • 芯科科技推出智能开发工具Simplicity Ecosystem软件开发套件开启物联网开发的新高度
  • 报错: lfstackPack redeclared in this block / go版本混乱,清理旧版本
  • 和鲸科技入选《大模型一体机产业图谱》,以一体机智驱科研、重塑教学
  • Go语言:关于怎么在线学习go语言的建议
  • 树 B树和B+树
  • 【arXiv2025】Real-Time Object Detection Meets DINOv3
  • 绍兴网站建设专业的公司4000-262-怎么在百度上发帖推广
  • AH2203输入12v输出3v 6v 9v/2A同步降压LED驱动器芯片
  • C如何调用Go
  • 使用Mathematica编写一个高效的Langevin方程求解器
  • 中国软件企业出海,为什么80%都选择这家服务商?
  • 《红黑树核心机制解析:C++ STL中map/set高效实现原理与工程实践》
  • Spring Boot 使用 Redis 实现消息队列
  • 从renderToString到hydrate,从0~1手写一个SSR框架
  • git报错no new changes、does not match any
  • 公司做网站的费用怎么做账望野作品
  • 【第五章:计算机视觉-项目实战之推荐/广告系统】2.粗排算法-(4)粗排算法模型多目标算法(Multi Task Learning)及目标融合
  • Prometheus 监控系统全维度指南
  • Gradle 增量构建与构建缓存:自定义 Task 如何实现 “只构建变化内容”?
  • 【笑脸惹桃花】1024,阶段性回望与小结
  • 农产品网站建设策划方案网站获取qq号码 代码
  • 网站服务器的作用和功能有哪些福田欧辉是国企吗
  • R语言高效数据处理-变量批量统计检验
  • 云图-地基云图
  • R语言基于selenium模拟浏览器抓取ASCO数据-连载NO.03
  • 多分组火山图绘制-Rscript_version1.0