SpringAOP注解方式监控方法执行情况

来源:互联网 发布:孤烟暮蝉 知乎 编辑:程序博客网 时间:2024/05/16 23:57

1、为什么要这么做?

答:有时候,我们需要监控一个方法的执行情况,比如花费时间、入参和结果,当然,我们可以直接在每个方法里面直接打印日志,但是这样太不灵活,每个方法需要的方法都要去加这样的代码,不需要时还要去掉,太麻烦了,不利于维护和重用。有没有一种方式,只需要在某个方法上添加一个注解,自然就可以监控此方法,不需要监控的时候,删除这个注解就可以了,有没有这样的解决方案呢?当然有。

2、如何做?

第一步:自定义注解

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface RunStatus {public String logLevel() default "debug";}

说明:java的Annotation没有什么可说的,就是标识而已,记住如何定义使用即可。

第二步:定义一个切面

@Component@Aspectpublic class MonitorAspect {private Logger logger = LoggerFactory.getLogger(MonitorAspect.class);//切点(切入所有注解为RunStatus的方法)@Pointcut("@annotation(com.hk515.mingyihuiinterface.annotation.RunStatus)")public void runStatusAnnotation(){}//通知(统计被切入方法的运行状态)@Around("runStatusAnnotation()")public Object runStatus(ProceedingJoinPoint point) throws Throwable{Method[] methods = point.getSignature().getDeclaringType().getMethods();//methods[0]是当前point所在的方法boolean annotationPresent = methods[0].isAnnotationPresent(RunStatus.class);Object proceed = null;if(annotationPresent){long start = System.currentTimeMillis();proceed = point.proceed();long end = System.currentTimeMillis();String logLevel = methods[0].getAnnotation(RunStatus.class).logLevel();//获取注解上所写的logLevelString info = "\n方法:{}\n入参:{}\n结果:{}\n耗时:{}毫秒,{}秒";if("debug".equals(logLevel)){logger.debug(info,methods[0],point.getArgs(),proceed,end-start,(end-start)/1000);}else if("info".equals(logLevel)){logger.info(info,methods[0],point.getArgs(),proceed,end-start,(end-start)/1000);}else{logger.info(info,methods[0],point.getArgs(),proceed,end-start,(end-start)/1000);}}else{proceed = point.proceed();}return proceed;}}

说明:还不懂SpringAOP的赶紧去学学,切面包含切点和通知,切点自然就是要切的位置了;通知有多种,意思是对所切位置的增强处理代码,我们把监控的逻辑写到这里即可。

第三步:如何使用?

直接在方法上加上@RunStatus注解就可以了。

@RunStatuspublic ModelResult<List<Area>> fetch(){//}


备注:记得在spring配置文件中开启aop代理,<aop:aspectj-autoproxy />


总结:原理也很简单,就是spring在启动的时候会扫描所有的方法,一旦发现某个方法上有@RunStatus注解,就会为此类生成代理类,并给将此方法用runStatus(ProceedingJoinPoint point) 包裹起来,执行目标方法前后会执行我们写的runStatus(ProceedingJoinPoint point)方法。

0 0
原创粉丝点击