最近在做一个springboot的项目,当我想要使用aop做一个统一的日志管理的时候,刚开始是可以使用的,但是后来不知道改了什么地方,这个aop日志就失灵。在网上找了很多文章,都没有解决,后来,仔细分析了一下,终于知道原因了。所以写这篇博客记录一下,希望能够帮助到相同遭遇的人。
1、首先,引入AOP启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、编写切面类
/*
日志切面处理,当用户访问博客时,将用户的ip,请求的URL,调用的方法,参数,
返回内容保存到日志中,利用AOP
*/
@Aspect //开启AOP
@Component //将这个类注册到容器中
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Pointcut("execution(* com.ewen.controller.*.*(..))")
public void log(){
}
@Before("log()")
public void doBefore(JoinPoint joinPoint) {
//获取 ServletRequestAttributes对象
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//利用ServletRequestAttributes对象获取HttpServletRequest对象
HttpServletRequest request = attributes.getRequest();
//获取url,使用getRequestURL()获取的是StringBuffer对象,需要转成String
String url = request.getRequestURL().toString();
String ip = request.getRemoteAddr();
//利用JoinPoint获得拦截的方法
String methodName = joinPoint.getSignature().getDeclaringTypeName()+"."
+ joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
RequestLog requestLog = new RequestLog(ip,url,methodName,args);
logger.info("Request : {}", requestLog);
System.out.println("指行了。。。");
}
//最终通知 :无论目标方法是否出现异常 最终通知都会 执行,将返回结果记录到日志中
@AfterReturning(returning = "result",pointcut = "log()")
public void doAfterReturn(Object result) {
logger.info("Result : {}", result);
}
//定义一个内部类来封装用户的ip,请求的URL,调用的方法,参数
public class RequestLog{
private String ip;
private String url;
private String methodName;
private Object[] args;
public RequestLog(String ip, String url, String methodName, Object[] args) {
this.ip = ip;
this.url = url;
this.methodName = methodName;
this.args = args;
}
@Override
public String toString() {
return "{" +
"ip='" + ip + '\'' +
", url='" + url + '\'' +
", methodName='" + methodName + '\'' +
", args=" + Arrays.toString(args) +
'}';
}
}
}
开始的时候,没有写后台管理,对controller
下的所有类的所有方法生效。但是,后来写后台管理,在controller
下建了一个admin
目录,AOP就对admin下的所有类失效了,失效的原因是切入点表达式"execution(* com.ewen.controller.*.*(..))"
不包含admin下的类,需要改为"execution(* com.ewen.controller.*.*.*(..))"
才可以。