首先配置好切面代码 打印日志
package com.rfca.aop;
import com.fasterxml.jackson.databind.ObjectMapper;
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.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Component
@Aspect
@Lazy(false)
public class Logaop {
private Logger logger = LoggerFactory.getLogger(Logaop.class);
// private final static String intfName = "Activity/starFireOrderDetailSyn";
/**
* 定义切入点:对要拦截的方法进行定义与限制,如包、类
*
* 1、execution(public * *(..)) 任意的公共方法
* 2、execution(* set*(..)) 以set开头的所有的方法
* 3、execution(* com.lingyejun.annotation.LoggerApply.*(..))com.lingyejun.annotation.LoggerApply这个类里的所有的方法
* 4、execution(* com.lingyejun.annotation.*.*(..))com.lingyejun.annotation包下的所有的类的所有的方法
* 5、execution(* com.lingyejun.annotation..*.*(..))com.lingyejun.annotation包及子包下所有的类的所有的方法
* 6、execution(* com.lingyejun.annotation..*.*(String,?,Long)) com.lingyejun.annotation包及子包下所有的类的有三个参数,第一个参数为String类型,第二个参数为任意类型,第三个参数为Long类型的方法
* 7、execution(@annotation(com.lingyejun.annotation.Lingyejun))
*/
@Pointcut("execution(* com.rfca.newcontroller..*.*(..))")
private void cutMethod() {
}
/**
* 后置通知:在目标方法执行后调用,若目标方法出现异常,则不执行 后置通知完成计件
*/
@Around("cutMethod()")
public Object myLogger(ProceedingJoinPoint pjp) throws Throwable {
long l = System.currentTimeMillis();
//使用ServletRequestAttributes请求上下文获取方法更多
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String className = pjp.getSignature().getDeclaringTypeName();
String methodName = pjp.getSignature().getName();
//使用数组来获取参数
Object[] array = pjp.getArgs();
ObjectMapper mapper = new ObjectMapper();
//执行函数前打印日志
logger.info("调用前:{}:{},传递的参数为:{}", className, methodName, mapper.writeValueAsString(array));
logger.info("URL:{}", request.getRequestURL().toString());
logger.info("IP地址:{}", request.getRemoteAddr());
//调用整个目标函数执行
Object obj = pjp.proceed();
//执行函数后打印日志
logger.info("调用后:{}:{},返回值为:{}", className, methodName, mapper.writeValueAsString(obj));
logger.info("耗时:{}ms", System.currentTimeMillis() - l);
return obj;
}
}
重点
需要在扫描controller的那个xml中配置 <aop:aspectj-autoproxy proxy-target-class=“true”/> 有时候配置到applicationContext.xml中是不生效的,
因为 切面类和 被代理的类都要由spring 或者springMVC管理
只有 Spring 生成的对象才有 AOP 功能,因为 Spring 生成的代理对象才有 AOP 功能。
切入的类和被切入的类必须是被spring管理的(springIOC),如果是自己new 出来的,切入无效。
而且所对应的切入方法不能是static 修饰的
可能是springmvc的bug吧。你把
aop:aspectj-autoproxy/
放到DispatcherServlet所对应的**-servlet.xml配置文件中,就可以了。
项目配置如下就可以生效了
结果