前文
日常的工作中,会有很多的地方需要记录日志,甚至在一些系统中,进行日志的展示,所以需要日志数据入库。很多的人会想到写一个公共的工具类进行调用,记录。这样的方法好处有两个。
- 数据可以动态封装
- 参数可以随便使用
当我第一次接触到的注解就是动态记录日志,但当时是读取的value值中写好的描述,当然可能有些少了些灵动性。废话不多说,直接进主题
切点
- 个人理解常用
@Retention
这个注解,用@Retention(RetentionPolicy.RUNTIME )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时,
所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用.@Target
这个注解的大概的意思就是告诉我们这个注解可以防止在那些位置上。一般都是参照ElementType
这个枚举,一般都是ElementType.METHOD
,意思是指放置在方法上,ps(因为我们的日志记录主要是对于方法的请求进行记录)。*- 一般注解都会携带一个value作为注解的值。可以记录是那个模板的功能,因为一般的日志展示列表,不都是只展示操作内容,也展示来自那个功能模块,所以这个功能模块可以提前写好。
接下来是代码块的提示
/**
* Created by YUEXINGZHONG on 2019-11-26-14:33
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DynamicLog {
String value() default "";
}
声明切面,完成日志记录
@Pointcut介绍
@Pointcut
统一切面ps
(这里添加一个切面注解的一些常用使用方法)
1)execution(* *(..))
//表示匹配所有方法
2)execution(public * com. loylaty.service.UserService.*(..))
//表示匹配com.loylaty.server.UserService中所有的公有方法
3)execution(* com.loylaty.server..*.*(..))
//表示匹配com.loylaty.server包及其子包下的所有方法
4)@annotation(com.loyalty.study.aop.annotations.MyLog):用于匹配当前执行方法持有指定注解的方法;
@Around介绍
单词的含义,顾名思义环绕,灵活的切入代码,好用。@Around介绍
其他的切面注解(@Before,@AfterReturning,@AfterThrowing,@After)
这里不做介绍,大家使用到可以自己去了解
接下来是代码介绍
/**
* Created by YUEXINGZHONG on 2019-11-27-10:59
*/
@Aspect
@Component
@Slf4j
public class DynamicLogAspect {
@Pointcut("@annotation(com.example.dameng.aop.DynamicLog)")
public void logPoint() {
}
@Around("logPoint()")
public Object around(ProceedingJoinPoint point) throws Throwable {
Object result = null;
// 执行方法
result = point.proceed();
// 保存请求日志
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
log.info("请求路径:" + request.getRequestURL());
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
log.info("请求方法:" + method.getName());
// 获取方法上LogFilter注解
DynamicLog logFilter = method.getAnnotation(DynamicLog.class);
String value = logFilter.value();
log.info("模块描述:" + value);
Object[] args = point.getArgs();
log.info("请求参数:" + JSONObject.toJSONString(args));
return result;
}
}
总结和问题
- 根据不同的业务需要定义不同的参数,方便进行记录,所有操作日志
- 相应的服务service注入,获取当前登录人以及角色进行业务记录
- 这些注解的负担和工具类到底哪个更加实用,不能只是因为注解是感觉高大上,当然我一开始学会写注解,就是感觉,很牛逼啊。哈哈哈 ,仁者见仁智者见智吧 ,注解还是很有意思的。希望有好的注解与我分享