使用Spring Aop自定义注解实现自动记录日志
百度加自己琢磨,以下亲测有效,所以写下来记录,也方便自己回顾浏览加深印象之类,有什么问题可以评论一起解决,不完整之处也请大佬指正,一起进步哈哈
(1)首先配置文件:
<!-- 声明自动为spring容器中配置@aspectj切面的bean创建代理 ,织入切面 --> <aop:aspectj-autoproxy /> <!-- 开启注解扫描 --> <context:component-scan base-package="com.ky.zhjd.**"/> <!-- 为true说明代理基于类被创建(默认false,基于接口被创建) --> <aop:config proxy-target-class="true"></aop:config>
(2)创建一个自定义注解类
注意创建时选Annotation,类名我叫ArchivesLog(日志档案的意思)。
ArchivesLog.java内容:
package com.ky.zhjd.common.log; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * 自定义注解类 * @author ddz * */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ArchivesLog { /** 要执行的操作类型比如:添加操作 **/ public String operationType() default ""; /** 要执行的操作名称比如:添加一条用户数据 **/ public String operationName() default ""; }
(3)新建一个切面类,我叫LogAspect.java
package com.ky.zhjd.common.log; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 切面类 * * @author ddz * */ @Aspect @Component("logAspect") public class LogAspect { private static final Logger log = LoggerFactory.getLogger(LogAspect.class); // 配置织入点 @Pointcut("@annotation(ArchivesLog)") public void logPointCut() { } /** * 前置通知 用于拦截操作,在方法返回后执行 * * @param joinPoint 切点 */ @AfterReturning(pointcut = "logPointCut()") public void doBefore(JoinPoint joinPoint) { handleLog(joinPoint, null); } /** * 拦截异常操作,有异常时执行 * * @param joinPoint * @param e */ @AfterThrowing(value = "logPointCut()", throwing = "e") public void doAfter(JoinPoint joinPoint, Exception e) { handleLog(joinPoint, e); } private void handleLog(JoinPoint joinPoint, Exception e) { try { // 获得注解 ArchivesLog controllerLog = getAnnotationLog(joinPoint); System.out.println("---------------自定义注解:" + controllerLog); if (controllerLog == null) { return; } // 获得方法名称 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); String type = controllerLog.operationType(); String name = controllerLog.operationName(); // 打印日志 这里可以进行插入数据库操作 log.info(">>>>>>>>>>>>>操作类型:", type); log.info(">>>>>>>>>>>>>操作名称:", name); log.info(">>>>>>>>>>>>>类名:", className); log.info(">>>>>>>>>>>>>方法名:", methodName); } catch (Exception exp) { // 记录本地异常日志 log.error("==前置通知异常=="); log.error("异常信息:", exp.getMessage()); exp.printStackTrace(); } } /** * 是否存在注解,如果存在就获取 */ private static ArchivesLog getAnnotationLog(JoinPoint joinPoint) throws Exception { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { // 拿到自定义注解中的信息 return method.getAnnotation(ArchivesLog.class); } return null; } }
(4)在方法上使用注解 , 然后调用该方法
@ArchivesLog(operationType="查询操作",operationName="查询一条用户详情") @RequestMapping(value = "/findByid", produces={"application/json;charset=UTF-8"}) public @ResponseBody BaseResult<Object> findByid(String id) { String s="11"; BaseResult<Object> r=userService.findById(s); System.out.println(r+">>>>>>>>>>"); return r; }
ok 上效果:
有什么不完善的地方欢迎指出,一起学习