使用 Spring AOP、Java 注解实现方法级别日志记录。

Java 注解

  1. /**
  2. * 日志注解
  3. *
  4. * @author yinjianwei
  5. * @date 2017年3月28日 下午6:00:54
  6. *
  7. */
  8. @Target(ElementType.METHOD)
  9. @Retention(RetentionPolicy.RUNTIME)
  10. @Documented
  11. public @interface Log {
  12. /**
  13. * 操作描述
  14. */
  15. String value() default "";
  16. }

日志切面处理类

  1. /**
  2. * 日志切面处理类
  3. *
  4. * @author yinjianwei
  5. * @date 2017年3月29日 上午9:14:37
  6. *
  7. */
  8. public class LogAspect {
  9. private final Logger logger = Logger.getLogger(this.getClass());
  10. private static final String LOG_CONTENT = "[类名]:%s,[方法]:%s,[参数]:%s,[内容]:%s";
  11. /**
  12. * 保存系统操作日志
  13. *
  14. * @param joinPoint
  15. * 连接点
  16. * @return 方法执行结果
  17. * @throws Throwable
  18. * @throws Exception
  19. * @throws @throws
  20. * Throwable 调用出错
  21. */
  22. @Around("@annotation(com.fclassroom.common.annotations.Log)")
  23. public Object logContent(ProceedingJoinPoint joinPoint) throws Throwable {
  24. // 解析Log注解
  25. String className = joinPoint.getTarget().getClass().getName();// 类名称
  26. String methodName = joinPoint.getSignature().getName();// 方法名称
  27. Object[] args = joinPoint.getArgs();// 方法参数
  28. Method method = currentMethod(joinPoint);
  29. Log log = method.getAnnotation(Log.class);
  30. String logContent = String.format(LOG_CONTENT, className, methodName, Arrays.toString(args), log.value());
  31. // 记录日志
  32. logger.info(logContent);
  33. // 方法执行
  34. return joinPoint.proceed();
  35. }
  36. /**
  37. * 获取当前执行的方法
  38. *
  39. * @param joinPoint
  40. * 连接点
  41. * @return 方法
  42. * @throws SecurityException
  43. * @throws NoSuchMethodException
  44. */
  45. private Method currentMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException, SecurityException {
  46. Signature signature = joinPoint.getSignature();
  47. MethodSignature methodSignature = null;
  48. if (!(signature instanceof MethodSignature)) {
  49. throw new IllegalArgumentException("该注解只能用于方法");
  50. }
  51. methodSignature = (MethodSignature) signature;
  52. Object target = joinPoint.getTarget();
  53. Method method = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
  54. return method;
  55. }
  56. }

Spring 配置

  1. <!-- 切面日志 -->
  2. <bean id="logAspect" class="com.fclassroom.common.aop.LogAspect">
  3. </bean>
  4. <aop:config>
  5. <aop:aspect ref="logAspect">
  6. <aop:pointcut id="logPointCut"
  7. expression="@annotation(com.fclassroom.common.annotations.Log)" />
  8. <aop:around pointcut-ref="logPointCut" method="logContent" />
  9. </aop:aspect>
  10. </aop:config>

使用日志

  1. Service类中增加日志注解
  2. @Log("test方法")
  3. @Override
  4. public void test(String name, Date today) {
  5. System.out.println("方法中内容");
  6. }

显示效果

  1. INFO|2017-03-30 09:53:07,957|10|11|1.2.3|com.fclassroom.common.aop.LogAspect|logContent(53)|[类名]:com.fclassroom.report.service.impl.ExamResultServiceImpl,[方法]:test,[参数]:[张三, Thu Mar 30 09:53:07 CST 2017],[内容]:test方法

方法中内容。

作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/bpkeiy 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。