您现在的位置是:首页 >技术交流 >SpringBoot中使用AOP备忘网站首页技术交流

SpringBoot中使用AOP备忘

划]破 2023-06-12 20:00:03
简介SpringBoot中使用AOP备忘

SpringBoot中使用AOP备忘

1. pom.xml中添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 示例代码

//	在类上添加@Aspect注解表明这是一个切面,
//	@Component注解是为了能够让spring的bean容器对齐进行管理,
//	@Pointcut定义切入点,自定义切入方法名,
//	@Befor,@After,等注解定义连接点,被这些注解的方法作为Advice(通知),
//				织入pointcut匹配的方法中。

@Aspect
@Component
public class HttpAspect {
 
    private static final Logger logger=LoggerFactory.getLogger(HttpAspect.class);
 
    //配置切点
    @Pointcut("execution(public * com.springboot.controller.GirlController.*(..))")
    public void log(){  // 这里的方法自定义,如test()
    }
 
    // joinPoint用于获取域切入点方法有关的信息
    @Before("log()")	// 此处方法名需和上方配置的切点名一致
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request=requestAttributes.getRequest();
        //url
        logger.info("url={}",request.getRequestURL());
        //method
        logger.info("method={}",request.getMethod());
        //ip
        logger.info("ip={}",request.getLocalAddr());
        //类方法
        logger.info("class_method={}",joinPoint.getSignature().getDeclaringType()+"."+joinPoint.getSignature().getName());
        //方法参数
        logger.info("args={}",joinPoint.getArgs());
    }
 
    @After("log()")
    public void doAfter(){
        logger.info("doAfter={}",2222222);
    }
 
    //得到response返回的数据,returning代表切入点方法返回的数据
    @AfterReturning(returning = "object",pointcut = "log()")
    public void doAfterReturning(Object object){
        logger.info("response={}",object.toString());
    }
}

3. 自定义注解 + AOP配置 + 切面类内部获取请求参数方法名等

3-1 创建一个注解类

// @Target 表示注解可以使用在哪里 (类上,方法上,参数上,字段上等)
// @Retention 注解保留多久, 一般使用runtime 可以使用反射
// 		source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
// 		class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
// 		runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在

import java.lang.annotation.*;
/**
 * 自定义注解
 */
@Target({ElementType.TYPE, ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CDS {
// 注解的参数 value 可以向注解中设置参数 默认值设置的 primary
    String value() default "primary";
}

3-2 创建一个切面类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

// 本例 只写了前置通知, 环绕通知要使用ProceedingJoinPoint
@Component
@Aspect
public class CAspect {
	// 这里写明切入点的位置是含有这个自定义注解的地方
    @Before("@annotation(cn.test.CDS))")
    public void befor(JoinPoint joinPoint){
        //1.获取切入点所在目标对象
        Object targetObj =joinPoint.getTarget();
        System.out.println(targetObj.getClass().getName());
        
        // 2.获取切入点方法的名字
        String methodName = joinPoint.getSignature().getName();
        System.out.println("切入方法名字:"+methodName);
        
        // 3. 获取方法上的注解
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null)
        {
            CDS2 apiLog=  method.getAnnotation(CDS2.class);
            System.out.println("切入方法注解的title:"+apiLog.value());
        }

        //4. 获取方法的参数 一一对应
        Object[] args = joinPoint.getArgs();
		//        获取参数名称 一一对应
        String[] parameterNames = methodSignature.getParameterNames();
		//        获取参数类型 一一对应
        Class[] parameterTypes = methodSignature.getParameterTypes();
        for(Object o :args){
            System.out.println("切入方法的参数:"+o);
        }
    }
}

3-3 自定义注解的使用

 @GetMapping("/info")
 @CDS   // 方法上添加自己写的注解即可,即可触发上方自写CAspect类中的环绕方法
 public void info( String userId){
	System.out.println("测试方法~~~~");
 }
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。