Java Web实战(五)Web后端之AOP-面向切面编程原理用法详解

AOP:Aspect Oriented Programming(面向切面编程、面向方面编程),其实就是面向特定方法编程。

1. 场景示例

案例部分功能运行较慢,定位执行耗时较长的业务方法,此时需要统计每一个业务方法的执行耗时

如何实现? 一种策略是为为每个执行方法都添加获取执行耗时的逻辑. 缺点在于: 它需要更改原先的所有的业务代码, 同时获取执行耗时的代码逻辑相同, 造成了大量重复.

一种解决思想是: 使用动态代理, 也即在执行指定的部分代码时会在合适的节点转到代理逻辑中执行. 动态代理是面向切面编程最主流的实现。而 SpringAOP 是Spring框架的高级技术,旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。

Spring AOP快速入门:统计各个业务层方法执行耗时

  1. 先引入 aop 依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    
  2. 连包带类创建并编写AOP程序: 针对于特定方法根据业务需要进行编程. 通过使用 @Aspect 注解来表明这是一个切面类, 该类同时还是一个 java-bean.

@Component
@Aspect
public class TimeAspect {
   
    @Around("execution(* com.itheima.service.*.*(..))")
    public Object recordTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
   
        long begin = System.currentTimeMillis();
        Object object = proceedingJoinPoint.proceed(); //调用原始方法运
        long end = System.currentTimeMillis();
        log.info(proceedingJoinPoint.getSignature()+"执行耗时: {}ms", end - begin);
        return object;
    }
}

2. AOP核心概念

连接点: JoinPoint, 可以被AOP控制的方法(暗含方法执行时的相关信息)
通知: Advice, 指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)
切入点: PointCut, 匹配连接点的条件,通知仅会在切入点方法执行时被应用
切面: Aspect, 描述通知与切入点的对应关系(通知+切入点)
目标对象: Target,通知所应用的对象

参考1中的程序, 其中 @Around("execution(* com.itheima.service.*.*(..))") 就是切入点, 引号内的表达式即为切入点表达式, 它规定了哪些类中的哪些方法需要被代理执行. @Around 注解是通知类型, 它指明了连接点在额外逻辑的执行位置, 这里是被环绕, 也即原方法执行前后均存在代理逻辑.

2.1 通知类型

通知类型
@Before(前置通知)
@After(后置通知)
@Around(环绕通知,重点)
@AfterReturning(返回后通知,了解)
@AfterThrowing(异常后通知,了解)

注解 通知类型 执行顺序
@Around 环绕通知 此注解标注的通知方法在目标方法前、后都被执行
@Before 前置通知 此注解标注的通知方法在目标方法前被执行
@After 后置通知 此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
@AfterReturning 返回后通知 此注解标注的通知方法在目标方法后被执行,有异常不会执行
@AfterThrowing 异常后通知 此注解标注的通知方法发生异常后执行
  • @Around环绕通知需要自己调用 ProceedingJoinPoint.proceed() 来让原始方法执行,其他通知不需要考虑目标方法执行
  • @Around环绕通知方法的返回值,必须指定为Object,来接收原始方法的返回值。

2.2 PointCut

@PointCut: 该注解的作用是将公共的切点表达式抽取出来,需要用到时引用该切点表达式即可。

@Pointcut("execution(* com.example.mytliasaop.controller.DeptController.getDeptById())")
public void allDeptCut(){
   }

@Around("allDeptCut()")
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值