hiway
hiway

Reputation: 3976

can annotation get context object?

Maybe title "can annotation get context object?" is not correct, but I don't know how to give it a right and clear one.

I use Spring AOP + Java Annotation to save log, here is my code:

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 is my own annotation, in my TrackAdvice class, I get the current executing method, if the method has a ServiceTracker annotation, then save the methodDesp in annotation to database.

Now the question is the methodDesp in annotation is dynamic, I want to get this object and retrieve its category property.

It seems that Java Annotation doesn't support this, maybe it supports but I don't know how.

Upvotes: 1

Views: 587

Answers (2)

Costi Ciudatu
Costi Ciudatu

Reputation: 38195

What you can do is use some sort of expression language in the annotation value and then run some interpreter in your advice code. One example using SPEL could look like this:

@ServiceTracker(methodDesp="save category, category name: #{category.name}")

And in your advice code, you can then extract the expression token, make use of a SpelExpression and pass it the target reference as root object (you may want to check what's available out of the box in the SPEL API for supporting your use-case(s)).

Upvotes: 2

Eugene Loy
Eugene Loy

Reputation: 12416

It seems that Java Annotation doesn't support this

You are correct - there is no way to do this in pure java.

The reason is that because annotations are static metadata that is wired into classes and defined at compile-time (this start to exist only at run-time, not compile-time).

In other words there is no straightforward way to make methodDesp of some annotated method of some class dynamic, since it's value has to be resolved statically, at compile-time.

However, technically there is a way to do something like you want. What I talk about is using javassist to either manipulate or create your classes (and annotations applied to them) at runtime. But be warned that this is rather hacky way and I generally would not recommend to go there.

Upvotes: 2

Related Questions