您现在的位置是:首页 >技术交流 >SpringBoot中使用AOP备忘网站首页技术交流
SpringBoot中使用AOP备忘
简介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("测试方法~~~~");
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。