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

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)方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值