使用 Spring AOP、Java 注解实现方法级别日志记录。
Java 注解
/**
* 日志注解
*
* @author yinjianwei
* @date 2017年3月28日 下午6:00:54
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
* 操作描述
*/
String value() default "";
}
日志切面处理类
/**
* 日志切面处理类
*
* @author yinjianwei
* @date 2017年3月29日 上午9:14:37
*
*/
public class LogAspect {
private final Logger logger = Logger.getLogger(this.getClass());
private static final String LOG_CONTENT = "[类名]:%s,[方法]:%s,[参数]:%s,[内容]:%s";
/**
* 保存系统操作日志
*
* @param joinPoint
* 连接点
* @return 方法执行结果
* @throws Throwable
* @throws Exception
* @throws @throws
* Throwable 调用出错
*/
@Around("@annotation(com.fclassroom.common.annotations.Log)")
public Object logContent(ProceedingJoinPoint joinPoint) throws Throwable {
// 解析Log注解
String className = joinPoint.getTarget().getClass().getName();// 类名称
String methodName = joinPoint.getSignature().getName();// 方法名称
Object[] args = joinPoint.getArgs();// 方法参数
Method method = currentMethod(joinPoint);
Log log = method.getAnnotation(Log.class);
String logContent = String.format(LOG_CONTENT, className, methodName, Arrays.toString(args), log.value());
// 记录日志
logger.info(logContent);
// 方法执行
return joinPoint.proceed();
}
/**
* 获取当前执行的方法
*
* @param joinPoint
* 连接点
* @return 方法
* @throws SecurityException
* @throws NoSuchMethodException
*/
private Method currentMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException, SecurityException {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = null;
if (!(signature instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
methodSignature = (MethodSignature) signature;
Object target = joinPoint.getTarget();
Method method = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
return method;
}
}
Spring 配置
<!-- 切面日志 -->
<bean id="logAspect" class="com.fclassroom.common.aop.LogAspect">
</bean>
<aop:config>
<aop:aspect ref="logAspect">
<aop:pointcut id="logPointCut"
expression="@annotation(com.fclassroom.common.annotations.Log)" />
<aop:around pointcut-ref="logPointCut" method="logContent" />
</aop:aspect>
</aop:config>
使用日志
Service类中增加日志注解
@Log("test方法")
@Override
public void test(String name, Date today) {
System.out.println("方法中内容");
}
显示效果
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 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。