Spring AOP

spring AOP 目前只支持对方法进行切面编程,如果想实现对字段的拦截,可以使用AspectJ

主要功能:日志记录,性能统计,安全控制,事务处理,异常处理

AOP概念:

名称 说明
切面(Aspect) 一个关注点的模块化,这个关注点可能会横切多个对象
连接点(Joinpoint) 程序执行过程中的某个特定的点。例如类初始化、方法执行、方法调用、字段调用或处理异常等等,Spring只支持方法执行连接点。
通知(Advice) 在切面的某个特定的连接点上执行的动作。(通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。)
切入点(Pointcut) 匹配连接点的断言,在AOP中通知和一个切入点的表达式。(例如某个类或方法的名称,Spring中允许我们方便的用正则表达式来指定)
引入(Introduction) 再不修改类代码的前提下,为类添加新的方法和属性。(也称为内部类型声明,为已有的类添加额外新的字段或方法,Spring允许引入新的接口(必须对应一个实现)到所有被代理对象(目标对象))
目标对象(Target Object) 被一个或多个切面所通知的对象。(需要被织入横切关注点的对象,即该对象是切入点选择的对象,需要被通知的对象,从而也可称为“被通知对象”;由于Spring AOP 通过代理模式实现,从而这个对象永远是被代理对象)
AOP代理(AOP Proxy) AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)
织入(Weaving) 把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象,     分为:编译时织入、类加载时织入、执行时织入。(将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期、运行期进行)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

AOP 的配置方式分为三种:API配置,XML配置,注解配置(下面以注解为例)

AOP的使用步骤:

 1、创建方面类

 2、声明配置切入点

 3、创建通知类(方便统一管理),并将通知类中的通知与某一切入点关联

实例

 使用注解@Aspect表示声明一个切面,但该注解不支持自动扫描,所以需要添加一个@Component注解,并且方面类本省不能成为目标类

官方解释如下:

 创建切面:

@Component
@Aspect
public class MyAspectJ {

    public MyAspectJ() {
        System.out.println("检测到AOP切面->"+this.getClass().getName());
    }
}

 AOP支持的切入点指示符(PCD)

 spring AOP支持的如下:

名称 说明
execution 用于匹配方法执行连接点。这是使用Spring AOP时使用的主要切入点指示符。
within 限制匹配某些类型中的连接点(使用Spring AOP时在匹配类型中声明的方法的执行)
this 限制与连接点的匹配(使用Spring AOP时执行方法),其中bean引用(Spring AOP代理)是给定类型的实例。
target 限制匹配连接点(使用Spring AOP时执行方法),其中目标对象(被代理的应用程序对象)是给定类型的实例。
args 限制与连接点的匹配(使用Spring AOP时执行方法),其中参数是给定类型的实例。
@target 限制与连接点的匹配(使用Spring AOP时执行方法),其中执行对象的类具有给定类型的注释。  
@args 限制与连接点的匹配(使用Spring AOP时执行方法),其中传递的实际参数的运行时类型具有给定类型的注释。
@within 限制匹配到具有给定注释的类型中的连接点(使用Spring AOP时执行在具有给定注释的类型中声明的方法)。
@annotation 限制连接点的匹配,其中连接点的主题(在Spring AOP中执行的方法)具有给定的注释。
bean 将连接点的匹配限制为特定的命名Spring bean或一组命名的Spring bean

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

spring 提供了一些表达式示例:

https://docs.spring.io/spring/docs/5.1.4.BUILD-SNAPSHOT/spring-framework-reference/core.html#aop-pointcuts-examples

 在切面中声明切入点:

@Component
@Aspect
public class MyAspectJ {

    public MyAspectJ() {
        System.out.println("检测到AOP切面->"+this.getClass().getName());
    }
    @Pointcut("execution(* getUserInfo(..))")
    public void nameIsGetUserInfoMethod() {}
  
    @Pointcut("execution(* com.aop.servilce.UserService.*(..))")
    public void anyPointcut(){}
}

 spring APO 共提供了5中通知:

@Before
前置通知,在切入点匹配的目标对象执行前执行
@After
后置通知,在切入点匹配的目标对象执行后执行
@AfterReturning
正常返回通知,在切入点匹配的目标对象执行后执行,并可以获取目标对象的某个方法的返回结果
@AfterThrowing
异常返回通知,在切入点匹配的目标对象执行出现异常时执行,并可以获取目标对象出现异常的具体类型
@Around
环绕通知,环绕通知围绕在连接点前后,比如一个方法调用的前后。能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行

 

创建通知:

@Component
@Aspect
public class MyAdvice {
    public MyAdvice() {
        System.out.println("检测到AOP通知类->"+this.getClass().getName());
    }
    @Before("com.aop.util.aop.aspectj.MyAspectJ.nameIsGetUserInfoMethod() && args(id,name)")
    public void before(String id,String name){
        System.out.println("前置通知!"+"---------------"+id+name);
    }

参考连接:

 https://docs.spring.io/spring/docs/5.1.4.BUILD-SNAPSHOT/spring-framework-reference/core.html#aop

 https://www.2cto.com/kf/201605/506004.html

 https://www.cnblogs.com/duanxz/p/6754606.html

原文地址:https://www.cnblogs.com/shiguotao-com/p/10142680.html