Spring AOP Advice的简单使用

本文深入探讨Spring AOP中的切面通知(Advice),包括@Before、@AfterReturning、@After和@Around等注解的使用方法。通过具体实例展示了如何在函数执行前后插入日志记录等操作,以及如何在切面中获取被通知方法的属性和Spring MVC的request实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring AOP为我们提供了切面通知(Advice)的功能,我们可以使用切面通知在函数的前后某些位置插入一些我们希望进行的操作,例如记录日志,检查合法性等等。

使用切面通知可以通过配置文件注解两种方式,本文仅讨论注解方式,因为配置文件方式太麻烦了,懒得弄。。。

需要引入的依赖包:

  • 使用切面通知需要引入相关的jar包:spring-aop.jar

  • 如果要使用注解的方式那么还需要引入:aspectjweaver.jaraopalliance.jar

一、一个简单的Advice

一个简单的切面通知实例

package com.baymax.study.study_springaop.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class StudyAdvice {

    //在被通知函数执行前执行
    @Before(value = "execution(void com.baymax.study.study_springaop.controller.*Controller.*Method*())")
    public void before(JoinPoint point) {
        System.out.println("before");
    }
	//在被通知函数返回后执行
    @AfterReturning("execution(void com.baymax.study.study_springaop.controller.*Controller.*Method*())")
    public void afterReturning(JoinPoint point) {
        System.out.println("after returning");
    }
	//在被通知函数执行完毕返回之前执行
    @After(value = "execution(void com.baymax.study.study_springaop.controller.*Controller.*Method*())")
    public void after(JoinPoint point) {
        System.out.println("after");
    }
	//环绕通知,在被通知函数执行前、后执行
    @Around(value = "execution(void com.baymax.study.study_springaop.controller.*Controller.*Method*())")
    public void around(ProceedingJoinPoint point) {
        try {
            System.out.println("around 1");
            point.proceed();//执行被通知函数
            System.out.println("around 2");
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

解析:

  • 使用**@Component**注解将该切面通知实例托管在Spring IoC容器中;
  • 使用**@Aspect**注解声明这是一个切面通知的实例;
  • 通过execution(void com.baymax.study.study_springaop.controller.Controller.Method*())定位到相应的被通知函数。

需要被通知的函数:

package com.baymax.study.study_springaop.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/study")
public class StudyController {
    @RequestMapping("/method1")
    public void studyMethod1() {
        System.out.println("in method 1");
    }
}

注意: 因为切面通知的功能实际上是基于Spring IoC容器扩展而来的功能,所以被通知的函数的实例必须是托管在Spring IoC容器中的,当然切面通知实例本身也需要被托管在Spring IoC容器中。

切面注解扫描

如果你的项目不是SpringBoot项目,而仅仅是Spring项目,那么需要在Spring 的配置文件中添加AOP的注解扫描,并且需要注意的是,这个配置一定要配置给你的切面所托管的容器。比如你的切面是托管给MVC子容器的,然后切面扫描仅仅配置给Spring 的父容器或者其它子容器,那么你的切面将不会被扫描到。

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

上述代码执行结果:

around 1
before
in method 1
around 2
after
after returning

结论:可以看到@Before注解标注的切面通知在被通知函数执行前执行,@After注解标注的切面通知在被通知函数执行完毕返回之前执行,@AfterReturning注解标注的切面通知在被通知函数返回后执行,@Around注解标注的切面通知可以在被通知函数执行前后分别执行一系列逻辑,从执行结果可以看到,around 1先于before执行,around 2先于after执行。

二、获取被通知的方法的属性

可以通过point.getSignature()获取到被通知函数的反射实例,然后进行一系列操作。

例如获取被通知函数的注解:

ActionDescription annotation = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(ActionDescription.class);

其他的一些操作和反射基本相同,需要用到时再自行探索。

三、在切面中如何获取到当前的Spring MVC的request实例

可以使用如下方法获取到当前的request:

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值