将变量传递给某个方面
问题描述:
我试图使用AOP和statsd的组合来测量我的代码中的度量。特别是,我希望开发人员能够只需添加注释的方法,并指定其名称和标签,如下创建一个定时器:将变量传递给某个方面
@Timed(name="executeHistoryDataSet", tags={dataSetInfo.getLabel()})
@Override
public String executeHistoryDataSet(DataSet dataSetInfo) throws DataServiceException {
String results = executeDataSet(dataSetInfo);
return results;
}
这将包括有关参数的标签信息。但是,这显示一个attribute value must be constant
错误,因为注释的参数不能是可变的,其中dataSetInfo.getLabel()
肯定不是。
开发人员可以在不创建新的方面和建议的情况下创建新的定时器(@Timed
可能是所有定时器的注释),所以有什么方法可以实现此功能,通过类似tags
的建议,但这可能不是恒定的,并且从方法到方法有所不同?
这里是注释本身:
public @interface Timed {
String name();
String[] tags();
}
而其方面:
@Aspect
public class MetricsAspects {
private static final StatsDClient statsd = new NonBlockingStatsDClient(
"my.prefix", //prefix to any stats
"statsd-host", //often "localhost"
8125, //port
"tag", "another tag" //tags always applied to stats
);
@Around ("execution(* *(..) && @annotation(timed)")
public Object timeAround(ProceedingJoinPoint point, Timed timed) throws Throwable {
String metricName = timed.name();
String[] metricTags = timed.tags();
long start = System.currentTimeMillis();
Object result = point.proceed();
long duration = System.currentTimeMillis() - start;
statsd.recordExecutionTime(metricName, duration, metricTags);
return result;
}
}
答
一个注释需要将其参数在编译时已知。由于在编译时不知道哪个对象被赋予了这个函数,只要它被执行,编译器就会抛出错误。
该错误有点误导。注释成员值需要是常量表达式,类文字或枚举常量。 –