也许标题“可以注释获取上下文对象吗?”是不正确的,但我不知道如何给它一个正确和明确的。
我使用Spring AOP + Java Annotation来保存日志,这是我的代码:
CategoryAction.java:
@ServiceTracker(methodDesp="save category, category name:"+this.category.getName())
public String save() throws Exception
{
this.categoryService.save(this.category);
this.setJsonDataSimply(null);
return "save";
}
TrackAdvice.java:
public Object trackAround(ProceedingJoinPoint point) throws Throwable
{
String log = "success";
ServiceTracker tracker = null;
Method method = null;
AbstractAction action = null;
try
{
Object result = point.proceed();
action = (AbstractAction) point.getTarget();
MethodSignature signature = (MethodSignature) point.getSignature();
method = signature.getMethod();
tracker = method.getAnnotation(ServiceTracker.class);
return result;
}
catch (Exception e)
{
log = e.getMessage();
throw e;
}
finally
{
if (tracker != null)
{
String userId = (String) ActionContext.getContext().getSession().get(Constant.USERID);
if (userId == null)
{
userId = "unknown";
}
TrackLog t = new TrackLog();
t.setWhen(new Date());
t.setUserId(userId);
t.setResult(log);
t.setMethodName(action.getClass().getCanonicalName() + "." + method.getName());
t.setMethodDesp(tracker.methodDesp());
this.trackService.save(t);
}
}
}
ServiceTracker
是我自己的注释,在我的TrackAdvice
类中,我得到当前的执行方法,如果方法有ServiceTracker
注释,则保存methodDesp
对数据库的注释。
现在的问题是注释中的methodDesp
是动态的,我希望得到this
对象并检索其category
属性。
似乎Java Annotation不支持这一点,也许它支持但我不知道如何。
答案 0 :(得分:2)
似乎Java Annotation不支持此
你是对的 - 在纯java中无法做到这一点。
原因是因为注释是静态元数据,它连接到类并在编译时(this
定义开始只在运行时存在,而不是在编译时存在。)
换句话说,没有简单的方法可以使某些类动态的注释方法methodDesp
,因为它的值必须在编译时静态解析。
然而,从技术上讲,有一种方法可以做你想要的事情。我所说的是使用javassist在运行时操作或创建类(以及应用于它们的注释)。但请注意,这是相当黑客的方式,我通常不建议去那里。
答案 1 :(得分:2)
您可以做的是在注释值中使用某种表达式语言,然后在您的建议代码中运行一些解释器。使用SPEL的一个示例可能如下所示:
@ServiceTracker(methodDesp="save category, category name: #{category.name}")
然后在您的建议代码中,您可以提取表达式标记,使用SpelExpression
并将target
引用作为根对象传递给它(您可能需要检查可用的内容) SPEL API中用于支持您的用例的框。