SpringBoot项目中使用AOP(面向切面编程技术)即使用@Aspect

很多时候我们需要在原有代码基础上对代码进行日志输出权限管控等可以使用aop技术,在不改变原来带有代码基础上进行操作

因为是springboot项目所以不需要写配置文件直接新建一个类,给类加上@Aspect注解 这个类就相当于一个切面类了

在编写切面类的前提是需要在pom.xml中引入依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
        <!-- SpringBoot 拦截器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

下面是切面类代码:类中有前置通知方法,后置通知方法,环绕通知等方法

package com.example.demo.aop;


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.rmi.runtime.Log;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;


/**
 * 对springboot中aop切面编程的测试
 */
//切面类
@Aspect
@Component
@Slf4j
public class AopAspect {
    private Logger logger = LoggerFactory.getLogger(AopAspect.class);
    Long timeStart;
    Long timeEnd;

    /***
     * 定义切入点
     */
    @Pointcut("execution(* com.example.demo.controller..*.*(..))")
    public void pointCut(){

    }

    /**
     * 前置增强:目标方法执行之前执行
     *
     * @param jp
     */
//    @Before("pointCut()") // 所有controller包下面的所有方法的所有参数
    public void beforeMethod(JoinPoint jp) {
        timeStart = System.currentTimeMillis();
        String methodName = jp.getSignature().getName();
        log.info("【前置增强】the method 【" + methodName + "】 ");
    }

    /**
     * 后置增强:目标方法执行之后执行以下方法体的内容,不管是否发生异常。
     *
     * @param jp
     */
//    @After("pointCut()")
    public void afterMethod(JoinPoint jp) {
        log.info("【后置增强】this is a afterMethod advice...");
        timeEnd = System.currentTimeMillis();
        float time = (float) ((timeEnd - timeStart)/1000);
        log.info("查询方法执行了---"+time+"-----");
    }
    /**
     * 返回增强:目标方法正常执行完毕时执行
     *
     * @param jp
     * @param result
     */
//    @AfterReturning(value = "pointCut()", returning = "result")
    public void afterReturningMethod(JoinPoint jp, Object result) {
        String methodName = jp.getSignature().getName();
        log.info("【返回增强】the method 【" + methodName + "】 ends with 【" + result + "】");
    }
    /**
     * 异常增强:目标方法发生异常的时候执行,第二个参数表示补货异常的类型
     *
     * @param jp
     * @param e
     */
//    @AfterThrowing(value = "pointCut()", throwing = "e")
    public void afterThorwingMethod(JoinPoint jp, Exception e) {
        String methodName = jp.getSignature().getName();
        log.error("【异常增强】the method 【" + methodName + "】 occurs exception: ", e);
    }
    /**
     * 环绕增强:目标方法执行前后分别执行一些代码,发生异常的时候执行另外一些代码
     *
     * @return
     */
    @Around(value = "pointCut()")
    public Object aroundMethod(ProceedingJoinPoint jp) {
        String methodName = jp.getSignature().getName();
        Object result = null;
        try {
            log.info("【环绕增强中的--->前置增强】:the method 【" + methodName + "】 begins with " + Arrays.asList(jp.getArgs())+"执行开始时间+"+System.currentTimeMillis());
            timeStart =System.currentTimeMillis();
            //执行目标方法
            result = jp.proceed();
            timeEnd= System.currentTimeMillis();
            log.info("【环绕增强中的--->返回增强】:the method 【" + methodName + "】 ends with " + result +"执行完的时间 "+System.currentTimeMillis());
        } catch (Throwable e) {
            result = "error";
            log.info("【环绕增强中的--->异常增强】:the method 【" + methodName + "】 occurs exception " + e);
        }
        log.info("【环绕增强中的--->后置增强】:-----------------end.----------------------");

        int time = (int) ((timeEnd - timeStart)/1000);
        log.info("方法执行时间---"+time+"秒------");
        return result;
    }

}

其中pointCut方法是切入点,execution(* com.example.demo.controller..*.*(..))是需要进行操作方法的包名,我这里是对controller包下面所有的方法进行管控,如果是想对某个方法进行操作,可以研究一下AOP的execution表达式

Spring Boot,我们可以使用@Aspect注解来定义一个切面类。切面类是用来定义切面的类,其可以包含各种通知和切点的定义。在切面类,我们可以使用@Pointcut注解定义一个切点,用来指定哪些方法会被切入。然后,我们可以使用@Before、@After、@Around等注解来定义各种通知,例如在方法执行之前或之后执行某些逻辑。最后,我们需要在切面类上使用@Aspect注解,将其标识为一个切面类。通过这样的方式,我们可以在Spring Boot项目使用@Aspect注解来实现AOP的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [SpringBoot项目使用AOP(面向切面编程技术)即使用@Aspect](https://blog.csdn.net/weixin_38340467/article/details/108150421)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [SpringBoot @Aspect注解详情](https://blog.csdn.net/DuShiWoDeCuo/article/details/78180803)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值