在项目中我们需要知道那个用户那个ip请求了那个接口,我们需要将日志写入数据库,来监控哪些功能在哪个时间段被哪些模块调用。这里使用的是spring AOP结合注解对Controller进行切面。
对于基础包这里没有列出
<!--aop所依赖的包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
/**
*自定义注解 拦截Controller
*/
@Target({ElementType.PARAMETER, ElementType.METHOD}) //作用范围为方法和参数
@Retention(RetentionPolicy.RUNTIME) //指定生命周期为内存可读
@Documented //指定其为注解
public @interface SystemControllerLog {
/**
* 操作说明
*/
public String description() default "";
}
/**
* 切点类
* @author tiangai
* @since 2014-08-05 Pm 20:35
* @version 1.0
*/
@Aspect
public class SystemLogAspect {
//注入Service用于把日志保存数据库
@Resource
private LogService logService;
//本地异常日志记录对象
private static final Logger logger = Logger.getLogger(SystemLogAspect.class);
//Controller层切点
@Pointcut("@annotation(com.hsy.aspect.SystemControllerLog)")
public void controllerAspect() {}
@AfterReturning(pointcut="controllerAspect()",returning="obj")
public void myAfterReturning(JoinPoint joinPoint,Object obj) {
logger.info("我是Controller层的返回通知");
logger.info("拿到返回的数据---->"+obj);
logger.info("拿到Controller注解描述"+ getControllerMethodDescription(joinPoint));
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param joinPoint 切点
* @return 方法描述
* @throws Exception
*/
public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
description = method.getAnnotation(SystemControllerLog. class).description();
break;
}
}
}
return description;
}
}
这里有一个坑一定要是springmvc不能是spring
<!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- 使用了@AspectJ注解的切面类 -->
<bean class="com.hsy.aspect.SystemLogAspect"/>
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
//此处为记录AOP拦截Controller记录用户操作
@SystemControllerLog(description = "登录账号")
public String selectUser(@RequestBody(required=true) Map<String,String> map ) throws Exception {
return "test";
}
在Postman中进行测试
成功
Spring AOP之Controller层AOP实现日志功能
原文:https://www.cnblogs.com/shaoyu/p/11882712.html