• spring 中 AOP 功能


    1 PointCut 由 ClassFilter 和 MethodMatcher 构成,通过 ClassFilter 定位到类上,通过 MethodMatcher 定位到方法。

    2 Spring 支持两种方法匹配器:静态方法匹配器和动态方法匹配器。

    静态方法匹配器仅对方法名签名进行匹配;动态方法匹配器会在运行期检查方法入参的值。

    静态匹配仅会匹配一次;动态匹配因为每次调用方法的入参可能不一样,所以每次调用都需要判断。因此动态匹配对性能影响比较大。

    3 Advisor 既包含切点代码又包含连接点信息(方法前、方法后)。切面可以分为三类:一般切面、切点切面和引介切面

    • Advisor:代表一般切面,仅包含一个 Advice ,因为 Advice 包含了横切代码和连接点信息。他代表的连接点是所有目标类的所有方法,因为该横切面太宽泛,所以一般不用。
    • PointcutAdvisor:代表具有切点的切面,包含 Advice 和 Pointcut 两类。
    • IntroductionAdvisor:引介切面,它应用于类层面上,所以使用 ClassFilter 定义

    4 基于配置使用@AspectJ 切面

    在配置文件中使用 

    <aop:aspectj-autoproxy />

    自动为 Spring 容器中那些匹配 @AspectJ 切面的 Bean 创建代理,完成切面织入。在 Spring 内部使用 AnnotationAwareAspectJAutoProxyCreator 进行自动代理的创建。

    它有一个属性 proxy-target-class,默认是 false,表示使用jdk 动态代理。当设置为 true 时,表示使用 CGLib 动态代理技术。不过即使设置为 false,如果目标类中没有接口,Spring 自动使用

    CGLib 动态代理。

    <aop:aspectj-autoproxy proxy-target-class="true" />

    5 Spring 支持9个 @AspectJ 切点表达式函数,根据描述对象的不同,可以分为 4 种类型

    在多个表达式之间使用  || , or 表示  或 ,使用  && , and 表示  与 , ! 表示 非

     例如:

    @Pointcut("execution(* com.huitong.controller..*.* (..)) " +
                "&& @annotation(org.springframework.web.bind.annotation.RequestMapping)")
        public void controllerPoint() {
        }

    6 切点函数入参使用通配符, @AspectJ 支持3种通配符。

    • “*”,匹配任意字符,但它只能匹配上下文中一个元素。
    • “..”,匹配任意字符,可以匹配多个元素;但在表示类时,必须和 * 联合使用。
    • “+”,按类型匹配指定类的所有类,必须跟在类名后面,如 com.smart.Car+。继承或扩展指定类的所有类,同时还包括指定类的本身。

    支持所有通配符:execution(),within()

    仅支持“+”通配符:args(),this(),target()

    不支持通配符:@args(),@within(),@target()

    7 @AspectJ 提供的增强类型

    • @Before ,该注解拥有两个成员,1)value用于定义切点  2)argNames,注解所标注增强方法的参数名
    • @AfterReturning 后置增强,有4个成员。1)value 用于定义切点  2)pointcut 表示切点信息。如果显示指定 pointcut 值,那么他将覆盖 value 的设置值。可将 pointcut 看做 value 同义词  3)returning 将目标对象方法的返回值绑定给增强的方法  4)argNames:如前所述
    • @Around,环绕增强,两个成员 1)value 用于定义切点  2)argNames:如前所述
    • @AfterThrowing,抛出增强,1)value 用于定义切点 2)pointcut 表示切点信息,如果显示指定 pointcut 值,那么他将覆盖 value 的设置值。  3)throwing 将抛出的异常绑定到增强方法中 4)argNames:如前所述
    • @After:不管是抛出异常还是正常退出,该增强都会得到执行。有两个成员,1)value 用于定位切点  2)argNames:如前所述

    8 execution()切点函数,需要定位到方法

    “.*”:表示包下所有类,“..*”:表示包、子孙包下的所有类。

    within(),类匹配模式串,只能定位到类,且不是接口。

    9 命名切点:使用 @Pointcut 注解及切面类方法对切点进行命名。

    如果在增强类型里面直接定义切点,这种称为匿名切点。

    例子如下:

    命名切点是用类方法作为切点名称,方法的访问修饰符控制了切点的可引用性。

    10 定义好切点后就可以在切面中通过名称引用切点。例子如下

    11 访问连接点信息 AspectJ 使用 JoinPoint 接口表示目标类连接点对象。如果是环绕增强,则使用 ProceedingJoinPoint 表示连接点对象,该类是

    JoinPoint 子接口。任何增强方法都可以通过第一个参数声明为 JoinPoint 访问连接上下文信息。

    11.2 ProceedingJoinPoint 继承于 JoinPoint 接口,它新增两个用于执行连接点的方法。

    例子如下:

  • 相关阅读:
    android_handler(二)
    android_handler(一)
    java_synchronized 用法
    android surfaView surfaHolder video 播放
    《Java 8 实战》读书笔记
    Java面试宝典——基础部分
    Shell脚本---处理用户输入
    《Spring》(十八)---- 事务管理
    《Spring》(十七)---- JDBC访问数据
    《Spring》(十六)---- 基于Schema的AOP
  • 原文地址:https://www.cnblogs.com/zhaopengcheng/p/7428929.html
Copyright © 2020-2023  润新知