暑期自学 Day 19 | Spring (五)

AOP 面向切面编程

通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

  • 作用:在程序运行期间,不修改源码对已有方法进行增强(动态代理)
  • 优势:减少重复代码,提高开放效率,方便维护
  • 实现:利用动态代理(详见____),在spring中,可以通过配置方式实现动态代理。

spring AOP的选择:看是否使用接口,选择使用基于接口还是基于子类的动态代理。(基于子类的动态代理也可以用于接口中。)

Spring 基于 xml 的 AOP 配置

就是把通知bean交给spring配置。比如说为每个方法创建数据库操作的事务时,需要用到开启,提交,回滚,释放事务的操作。如果每个方法都写这些操作过程,会造成代码的重复。利用AOP配置,可以有效减少这部分的代码量,提高编程效率,也使代码更容易维护。

操作步骤:

在bean.xml文件中

  1. 使用<aop:config>标签标示开始配置
  2. 使用<aop:aspect>表示配置的切面
    id:切面的唯一标示
    ref: 指定通知类bean的id
  3. aop:aspect标签内部使用对应标签来配置通知的类型
    通知类型分为五种,前置(before),后置(afterReturning),异常(afterThrowing),最终(after),环绕(around)
    • aop:xxx:
      • method属性,用于指定哪个方法属于该类通知;
        • pointcut:用于指定使用该通知的切入点方法
        • pointcut-ref:用于引入配置好的切入点表达式
  4. 配置切入点表达式:
    • <aop:pointcut id="pt1" expression="execution(* service.impl.*.*(..))"/>
通知类型
  • 前置,后置,异常,最终顾名思义

  • 环绕通知 - spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式

    • 问题:当我们配置了环绕通知之后,切入点方法没有执行,而通知方法执行了。
    • 分析:通过对比动态代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,而我们的代码中没有。
    • 解决:Spring框架为我们提供了一个接口:ProceedingJoinPoint。该接口有一个方法proceed(),此方法就相当于明确调用切入点方法。该接口可以作为环绕通知的方法参数,在程序执行时,spring框架会为我们提供该接口的实现类供我们使用。
切入点表达式的写法
  • 标准写法

    • 关键字:execution(表达式)
    • 表达式:
      • 访问修饰符 返回值 包名.包名 包名.包名 包名.包名 包名.包名…类名.方法名(参数列表)
      • public void service.impl.AccountServiceImpl.saveAccount()
  • 通配符写法

    • 访问修饰符可省略;

    • 返回值可使用通配符,表示任意返回值;

    • 包名使用通配符, 有几级包写几个*.,可以使用..表示当前包和子包

    • 方法名和类名都可以使用*通配

    • 参数列表可以写参数类型:基本型直接写名称,引用型写包名.类名

    • 可以用通配符表示任意类型,但是必须有参数

    • 用..表示有无参数均可

    • 全通配写法

      • * *..*.*(..)
    • 实际开发中通常写法最好要切到业务层实现类下的所有方法

      • * service.impl.*.*(..)

AOP基于注解的配置

所有的基于xml的配置均可以改为通过注解配置。

配置步骤:

  • 首先需要声明我们在通过注解方法配置AOP
    • @EnableAspectAutoProxy 或者 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • IOC容器的基于注解配置详见之前的笔记
  • 在需要作为切面的类前加@Aspect注解
  • 在切面类中声明@Pointcut切入点表达式
    • @Pointcut("execution(* spring.selflearning.service.impl.*.*(..))") private void pt1(){};
  • 为每个方法配置相应的通知类注解,并引入切入点表达式
    • @Around("pt1()")

说明

通过注解配置AOP,后置通知会晚于最终通知出现,这个问题可以通过配置环绕通知来解决。

代码链接

基于子类的动态代理
AOP配置
AOP通知类型

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!