SpringAOP注解方式监控方法执行情况
2016-03-15 09:42
639 查看
1、为什么要这么做?
答:有时候,我们需要监控一个方法的执行情况,比如花费时间、入参和结果,当然,我们可以直接在每个方法里面直接打印日志,但是这样太不灵活,每个方法需要的方法都要去加这样的代码,不需要时还要去掉,太麻烦了,不利于维护和重用。有没有一种方式,只需要在某个方法上添加一个注解,自然就可以监控此方法,不需要监控的时候,删除这个注解就可以了,有没有这样的解决方案呢?当然有。
2、如何做?
第一步:自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RunStatus {
public String logLevel() default "debug";
}
说明:java的Annotation没有什么可说的,就是标识而已,记住如何定义使用即可。
第二步:定义一个切面
@Component
@Aspect
public 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();//获取注解上所写的logLevel
String 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注解就可以了。
@RunStatus
public ModelResult<List<Area>> fetch(){
//
}
备注:记得在spring配置文件中开启aop代理,<aop:aspectj-autoproxy />
总结:原理也很简单,就是spring在启动的时候会扫描所有的方法,一旦发现某个方法上有@RunStatus注解,就会为此类生成代理类,并给将此方法用runStatus(ProceedingJoinPoint point) 包裹起来,执行目标方法前后会执行我们写的runStatus(ProceedingJoinPoint point)方法。
答:有时候,我们需要监控一个方法的执行情况,比如花费时间、入参和结果,当然,我们可以直接在每个方法里面直接打印日志,但是这样太不灵活,每个方法需要的方法都要去加这样的代码,不需要时还要去掉,太麻烦了,不利于维护和重用。有没有一种方式,只需要在某个方法上添加一个注解,自然就可以监控此方法,不需要监控的时候,删除这个注解就可以了,有没有这样的解决方案呢?当然有。
2、如何做?
第一步:自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RunStatus {
public String logLevel() default "debug";
}
说明:java的Annotation没有什么可说的,就是标识而已,记住如何定义使用即可。
第二步:定义一个切面
@Component
@Aspect
public 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();//获取注解上所写的logLevel
String 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注解就可以了。
@RunStatus
public ModelResult<List<Area>> fetch(){
//
}
备注:记得在spring配置文件中开启aop代理,<aop:aspectj-autoproxy />
总结:原理也很简单,就是spring在启动的时候会扫描所有的方法,一旦发现某个方法上有@RunStatus注解,就会为此类生成代理类,并给将此方法用runStatus(ProceedingJoinPoint point) 包裹起来,执行目标方法前后会执行我们写的runStatus(ProceedingJoinPoint point)方法。
相关文章推荐
- java-注解annotation
- 使用zabbix监控Nginx活动状态--Part1
- C#实现简单屏幕监控的方法
- C#进程监控方法实例分析
- Windows下使用性能监视器监控SqlServer的常见指标
- Android编程实现监控各个程序流量的方法
- Zabbix监控Linux主机设置方法
- Zabbix监控交换机设置方法
- 使用zabbix监控mongodb的方法
- Shell脚本实现Linux系统和进程资源监控
- Oracle 监控索引使用率脚本分享
- 获取键盘键的值 集合 方便监控键盘事件
- 一个监控Squid运行进程数并自动重启的简洁Shell脚本分享
- Linux下用Python脚本监控目录变化代码分享
- Java Annotation Overview详解
- 详解JDK 5 Annotation 注解之@Target的用法介绍
- Shell脚本编写Nagios插件监控程序资源占用
- Shell脚本实现监控kingate并自动启动
- Shell脚本监控网站页面正常打开情况
- shell脚本监控系统负载、CPU和内存使用情况