AOP概述

1.什么是AOP?

AOP是一种设计思维,在不批改源代码的状况下给程序动静对立增加额定性能的一种技术,如图:

2.AOP利用原理剖析

AOP底层基于代理机制(动静形式)实现性能扩大:
1):如果指标对象(被代理对象)实现接口,则底层能够采纳JDK动静代理机制为指标对象创立代理对象(指标类和代理类会实现独特接口)。
2):如果指标对象(被代理对象)没有实现接口,则底层能够采纳CGLIB代理机制为指标对象创立代理对象(默认创立的代理类会继承指标对象类型)。
如图:

AOP默认应用CGLIB代理,如需应用JDK代理配置文件配置:

spring.aop.proxy-target-class=false

基于JDK代理形式实现:

基于CGLIB代理形式实现:

AOP相干术语:

切面(aspect):个别为一个具体类(@Aspect注解正文)切入点()

告诉(Advice):在切面的某个特定点上执行的扩大

切入点(pointcut):应用@Pointcut注解进行切入点的形容,应用bean表达式定义切入点,语法:bean(spring容器中治理的某个bean的名字),bean表达式是一种粗粒度的切入点表达式(不能具体到bean中哪个办法)需写一个办法作为承载切入点

连接点(joinpoint):封装了切入点汇合办法中的某个正在执行的指标办法

AOP增加的依赖:

<dependency> <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-aop</artifactId>

</dependency>

注解阐明:

  • @Aspect 注解用于标识或者形容AOP中的切面类型,基于切面类型构建的对象用于为指标对象进行性能扩大或控制目标对象的执行。
  • @Pointcut注解用于形容切面中的办法,并定义切面中的切入点(基于特定表达式的形式进行形容),在本案例中切入点表达式用的是bean表达式,这个表达式以bean结尾,bean括号中的内容为一个spring治理的某个bean对象的名字。
  • @Around注解用于形容切面中办法,这样的办法会被认为是一个盘绕告诉(外围业务办法执行之前和之后要执行的一个动作),@Aournd注解外部value属性的值为一个切入点表达式或者是切入点表达式的一个援用(这个援用为一个@PointCut注解形容的办法的办法名)。
  • ProceedingJoinPoint类为一个连接点类型,此类型的对象用于封装要执行的指标方

告诉类型(告诉-Advice形容的是一种扩大业务):

1.@Before。(指标办法执行之前执行)
2.@AfterReturning。(指标办法胜利完结时执行)
3.@AfterThrowing。(指标办法异样完结时执行)
4.@After。(指标办法完结时执行)
5.@Around.(重点把握,指标办法执行前后都能够做业务拓展)(优先级最高)

阐明:在切面类中应用什么告诉,由业务决定,并不是说,在切面中要把所有告诉都写上。

切入点表达式加强:

**

bean表达式(重点)

bean表达式个别利用于类级别,实现粗粒度的切入点定义,案例剖析:

  • bean("userServiceImpl")指定一个userServiceImpl类中所有办法。
  • bean("*ServiceImpl")指定所有后缀为ServiceImpl的类中所有办法。

阐明:bean表达式外部的对象是由spring容器治理的一个bean对象,表达式外部的名字应该是spring容器中某个bean的name。

缺点:不能准确到具体方法,也不能针对于具体模块包中的办法做切入点设计

===========================================================

within表达式(理解)

within表达式利用于类级别,实现粗粒度的切入点表达式定义,案例剖析:

  • within("aop.service.UserServiceImpl")指定以后包中这个类外部的所有办法。
  • within("aop.service.*") 指定当前目录下的所有类的所有办法。
  • within("aop.service..*") 指定当前目录以及子目录中类的所有办法。

within表达式利用场景剖析:

1)对所有业务bean都要进行性能加强,然而bean名字又没有规定。

2)按业务模块(不同包下的业务)对bean对象进行业务性能加强。

===========================================================

execution表达式(理解)

execution表达式利用于办法级别,实现细粒度的切入点表达式定义,案例剖析:

语法:execution(返回值类型 包名.类名.办法名(参数列表))。

  • execution(void aop.service.UserServiceImpl.addUser())匹配addUser办法。
  • execution(void aop.service.PersonServiceImpl.addUser(String)) 办法参数必须为String的addUser办法。
  • execution( aop.service...*(..)) 万能配置。

===========================================================

@annotation表达式(重点)

@annotaion表达式利用于办法级别,实现细粒度的切入点表达式定义,案例剖析

  • @annotation(anno.RequiredLog) 匹配有此注解形容的办法。
  • @annotation(anno.RequiredCache) 匹配有此注解形容的办法。

其中:RequiredLog为咱们本人定义的注解,当咱们应用@RequiredLog注解润饰业务层办法时,零碎底层会在执行此办法时进行日扩大操作。

切面优先级设置实现

切面的优先级须要借助@Order注解进行形容,数字越小优先级越高,默认优先级比拟低。
列如:@Order(1),@Order(2)