Spring 面向切面编程AOP

本文详细介绍了Spring的面向切面编程(AOP)概念,包括定义、AOP术语、实现原理及XML和注解两种配置方式的应用实例。AOP通过将横切关注点(如日志、事务)与核心业务逻辑分离,降低了代码的重复性和耦合度。Spring AOP支持JDK动态代理和CGLIB代理,根据目标对象是否实现接口选择合适的代理方式。
摘要由CSDN通过智能技术生成

一、前言

  Spring提供了两个核心功能,一个是IoC(控制反转),另外一个便是AOP(面向切面编程),IoC有助于层与层之间纵向依赖的解耦,AOP则可以实现横向依赖之间的解耦。本文着重来讲面向切面编程的概念解析,实现原理以及应用实例。

二、基本概念

1、定义

  AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种纵向的对象层次关系结构。但OOP并不适合定义横向的关系,例如日志功能。代码往往横向地散布在所有对象层次中,而它又体现出与核心业务代码的无关性,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

  AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,权限认证、日志、事务等则是横切关注点。如果我们将横切关注点从业务逻辑代码中划分出来,并封装成为可重用模块。并在运行时,再动态地将横切关注点织入到核心关注点的指定方法、指定位置上。这样则便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

AOP图解

image

2、AOP术语

  • 增强(Advice)

  也就是上面说的日志、性能、安全、事务、异常等横切逻辑功能,是由 aspect 添加到特定的 join point (即满足point cut 规则的 join point) 的一段代码。

增强的五种类型:
    Before:前置增强,在方法被调用之前调用;
    After:后置增强,在方法完成后调用增强,无论方法是否执行成功;
    After-returning:后置成功增强,在方法成功执行之后调用增强;
    After-throwing:后置异常增强,在方法抛出异常后调用增强;
    Around:环绕增强,在方法调用前后分别调用增强。
  • 连接点(Joinpoint)

  程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就称为“连接点”。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。

  • 切点(Pointcut)

  在众多连接点中,选择使用增强的位置(通过execution(* com.lapland.demo..*(..)) 切入点表达式筛选)叫做切点。

切入点表达式:
    关键字:execution(表达式)
    表达式语法:
        [访问修饰符]  返回值  包名.类名.方法名(参数列表)
    全匹配方式:
        execution(public void cn.itcast.service.impl.UserServiceImpl.saveUser())
    访问修饰符可以不写:
        execution(void cn.itcast.service.impl.UserServiceImpl.saveUser())
    返回值可以使用通配符:通配符*
        execution(* cn.itcast.service.impl.UserServiceImpl.saveUser())
    包名可以使用通配符:当使用通配符时,有几级包,写几个*
        execution(* *.*.*.*.UserServiceImpl.saveUser())
    包名称可以使用..,表明的是当前包及其子包
        execution(* cn..UserServiceImpl.saveUser())
    类名可以使用通配符:
        execution(* cn..*.saveUser())
    方法名可以使用通配符:
        execution(* cn..*.*())
    参数列表可以指定类型:注意的是,如果是基本类型直接写类型名称,如果是引用类型,需要些包名.类名。lang也必须写。例如:java.lang.String
        execution(* *..*.*(int))
    参数列表可以使用通配符:注意:不能表示有无参数均可。只能表示参数的数据类型是任意的
        execution(* *..*.*(*))
    有无参数均可,可以使用..来表示:
        execution(* *..*.*(..))
    最简版:
        execution(* *..*.*(..))
    建议的写法:
        切到业务层具体实现类即可:
        execution(* cn.itcast.service.impl.*.*(..))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值