springboot基于aop的切面日志
yhmoling 人气:0通过aop的切面方式实现日志
通切面拦截所有指定包下的所有方法
@Aspect @Component @EnableAspectJAutoProxy public class LogAspect1{ Logger logger = LoggerFactory.getLogger(LogAspect.class); /** * 拦截切点 */ @Pointcut("execution(*xx.xx.controller.*.*(..))") private void logPointCut() { logger.info("进入注解拦截"); } //前置通知,在方法之前通知 @Before(value = "logPointCut()") public void before(JoinPoint jp) { logger.info("方法调用前:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName()); } //后置通知 @After(value = "logPointCut()") public void doAfter(JoinPoint jp) { logger.info("方法调用结束:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName()); } //环绕通知 @Around("logPointCut()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { logger.info("方法开始调用》》》》》》"); Object retVal = pjp.proceed(); logger.info("方法调用结束》》》》》》"); return retVal; } //返回通知 @AfterReturning(pointcut = "logPointCut()") public void doAfterReturning(JoinPoint jp) { logger.info("写入日志"); } //异常通知 @AfterThrowing(pointcut = "logPointCut()", throwing = "ex") public void doAfterThrowing(JoinPoint jp, Throwable ex) { logger.info("方法异常,异常信息:" + ex.getMessage()); } }
拦截自定义注解
定义一个日志注解,在所有要需要记录的方法上加盖注解即可被后续的aop拦截处理
代码如下
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log { /** * 日志主题 */ public String title() default ""; /** * 操作具体业务 */ public String business() default ""; /** * 是否保留请求参数 */ public boolean isSaveRequestData() default false; /** * 日志的类别,主要用于日志的分开记录和查询 **/ LogType logType() default LogType.LOGIN; }
拦截切面的实现
@Aspect @Component @EnableAspectJAutoProxy public class LogAspect { Logger logger = LoggerFactory.getLogger(LogAspect.class); @Autowired private ServiceDemo serviceDemo; /** * 拦截切点 */ @Pointcut("@annotation(moling.evolution.demo.aop.annotation.Log)") private void logPointCut() { } //前置通知,在方法之前通知 @Before(value = "logPointCut()") public void before(JoinPoint jp) { logger.info("方法调用前:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName()); } //后置通知 @After(value = "logPointCut()") public void doAfter(JoinPoint jp) { logger.info("方法参数:{}", jp.getArgs()); logger.info(" {} || {}", jp.getStaticPart().getId(), jp.getStaticPart().getSourceLocation()); jp.getStaticPart().getId(); logger.info("方法调用结束:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName()); } //环绕通知 @Around("logPointCut()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { logger.info("方法开始调用》》》》》》"); Object retVal = pjp.proceed(); logger.info("方法调用结束》》》》》》"); return retVal; } //返回通知 @AfterReturning(pointcut = "logPointCut()", returning = "object") public void doAfterReturning(JoinPoint jp, Object object) { System.out.println("返回通知"); Log log = null; try { log = getAnnotationLog(jp); } catch (Exception e) { e.printStackTrace(); } System.out.println(object); System.out.println(log); if (log != null) { logger.info(log.title()); logger.info(log.business()); logger.info(log.user()); logger.info(log.isSaveRequestData() + ""); } else { logger.error("获取注解信息失败"); } serviceDemo.demo(); } //异常通知 @AfterThrowing(pointcut = "logPointCut()", throwing = "ex") public void doAfterThrowing(JoinPoint jp, Throwable ex) { logger.info("方法异常,异常信息:" + ex.getMessage()); serviceDemo.error(); } /** * 是否存在注解,如果存在就获取 */ private Log getAnnotationLog(JoinPoint joinPoint) throws Exception { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { return method.getAnnotation(Log.class); } return null; } }
基于事件通知实现日志的记录
- 拦截切面的实现
@Aspect @Component @EnableAspectJAutoProxy public class LogAspectContext { Logger logger = LoggerFactory.getLogger(LogAspectContext.class); @Autowired private ApplicationContext applicationContext; /** * 拦截切点 */ @Pointcut("@annotation(moling.evolution.demo.aop.annotation.Log)") private void logPointCut() { logger.info("进入注解拦截"); } //返回通知 @AfterReturning(pointcut = "logPointCut()", returning = "object") public void doAfterReturning(JoinPoint jp, Object object) throws Exception { applicationContext.publishEvent(new LogSuccessEvent(jp, null)); } //异常通知 @AfterThrowing(pointcut = "logPointCut()", throwing = "ex") public void doAfterThrowing(JoinPoint jp, Throwable ex) { logger.info("方法异常,异常信息:" + ex.getMessage()); applicationContext.publishEvent(new LogSuccessEvent(jp, ex)); } /** * 是否存在注解,如果存在就获取 */ private Log getAnnotationLog(JoinPoint joinPoint) throws Exception { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { return method.getAnnotation(Log.class); } return null; } }
@Slf4j @Service public class ApplicationListener implements org.springframework.context.ApplicationListener<LogSuccessEvent> { @Autowired private ServiceDemo demo; @Override public void onApplicationEvent(LogSuccessEvent event) { JoinPoint joinPoint = event.getJp(); Throwable ex = event.getThrowable(); if (ex == null) { demo.demo(); } else { demo.error(); } } }
@Slf4j public class LogSuccessEvent extends ApplicationEvent { /** * Create a new ApplicationEvent. * * @param source the component that published the event (never {@code null}) */ private JoinPoint jp; private Throwable throwable; public LogSuccessEvent(Object source, Throwable throwable) { super(source); this.throwable = throwable; this.jp = (JoinPoint) source; // Log logger = (Log) source; // log.info(logger.title()); // log.info(logger.business()); // log.info(logger.user()); // log.info(logger.isSaveRequestData() + ""); } public JoinPoint getJp() { return jp; } public Throwable getThrowable() { return throwable; } }
加载全部内容