Spring两大核心思想:
1.IoC
2.AOP
AOP面向切面编程
Aspect Oriented Programing
切面就是指某一类特定问题,所以AOP也可以理解为面向特定方法编程.
它也是一种思想,是对一类事情的集中处理.
比如,统一数据返回格式和统一异常处理都是AOP思想的一种思想.
针对执行每个业务方法的耗时这个特定方法,通过AOP思想,在不改动原始方法的基础上,针对这个特定方法进行功能的增强.
实现:
(1)引入AOP依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
(2)编写AOP程序
说明:
@Aspect表示这是一个切面类
@Around环绕通知,在目标方法的前后都会被执行,后面的表达式表示对哪些方法进行增强.
ProceedingJoinPoint.proceed() 让原始?法执?
通过这个程序完成了业务接口执行耗时的统计.可以看出AOP面向切面编程的一些优势
1.代码无侵入:不修改原始的业务方法,就可以对原始的业务方法进行功能的增强或者是功能的改变.
2.减少了重复代码
3.提高开发效率
4.维护方便
作用是提供一组规则告诉程序对哪些方法进行功能增强
满足切点表达式规则的方法,就是连接点,也就是可以被AOP控制的方法
如果切点是 :? execution(* com.example.demo.controller.*.*(..))
那么 com.example.demo.controller路径下的方法,都是连接点.
通知就是具体要做的工作,指那些要重复的逻辑.
切面=切点+通知
作用:描述了当前AOP程序需要针对哪些方法,在什么时候执行什么操作.
切面所在的类,我们一般称为切面类. (用@Aspect注解标识)
Spring AOP的通知类型有以下几种:
Around? | 环绕通知, 此注解标注的通知?法在?标?法前, 后都被执? |
Before | 前置通知, 此注解标注的通知?法在?标?法前被执? |
After | 后置通知, 此注解标注的通知?法在?标?法后被执?, ?论是否有异常都会执? |
AfterReturning | 返回后通知, 此注解标注的通知?法在?标?法后被执?, 有异常不会执? |
AfterThrowing | 异常后通知, 此注解标注的通知?法发?异常后执? |
程序正常运行,@AfterThrowing标识的通知方法不会执行,其他类型的执行顺序如下:
@Around 标识的通知?法包含两部分, ?个"前置逻辑", ?个"后置逻辑".其 中"前置逻辑" 会先于 @Before 标识的通知?法执?, "后置逻辑" 会晚于 @After 标识的通知?法执?
如果有异常情况下:
注意事项:
? @Around 环绕通知需要调? ProceedingJoinPoint.proceed() 来让原始?法执?, 其他通知不需要考虑?标?法执?.
? @Around 环绕通知?法的返回值, 必须指定为Object, 来接收原始?法的返回值, 否则原始?法执 ?完毕, 是获取不到返回值的.
? ?个切?类可以有多个切点.
用这个注解可以定义一个公共的切点表达式,需要使用的时候直接引入就可以.
注意:
1.如果切点定义成private修饰,仅能在当前切面类使用
2.其他切面类要使用需要改成public,使用全限定类名引用: 全限定类名.方法名( )
切面优先级
当多个切面类的多个切入点都匹配都同一个目标方法时,当目标方法运行的时候,这些切面类的通知方法都会执行.
它们的执行顺序默认是按照切面类的类名字母排序的.
对于@Before通知:字母排名靠前的先执行
对于@After通知:字母排名靠前的后执行.
Spring提供了@Order注解来控制通知的执行顺序.
执行顺序:先执行优先级高的切面,再执行优先级低的切面,最后执行目标方法.
有两种常用的表达式
根据方法的签名进行匹配
切点表达式?持通配符表达:
步骤:
5.2.1编写自定义注解
创建一个注解类(选择Annotation)
代码:
5.2.2使用@annotation表达式来描述切点
5.2.3在连接点的方法上添加自定义注解
面试题
Spring AOP的实现方法
1.基于注解@Aspect
2.基于自定义注解 @Annotation
3.基于Spring API(通过xml配置的方式,现在很少用了)
4.基于代码实现(笨重,不推荐)