Results 1 to 8 of 8

Thread: Custom Annotation Processing

  1. #1

    Question Custom Annotation Processing

    Hi,

    I would like to be able to annotate my services with a custom annotation, and run some AOP-like code only on those methods. I know I can do this with standard AOP and @Apsect annotations, but instead of defining in the aspect itself (or xml) which methods will be intercepted, I want to define it in every method I need, to have more visibility when coding and reviewing/code maintenance.

    An example would be to perform some lock checking on specific methods. I would like to do the following

    @Lockable
    public void performBankTransaction(....)

    And because that method is annotated with @Lockable, execute some code before it (that would lock based on some condition).

    As a super bonus, I would also like to be able to annotate a parameter in the method to control concurrency, like so:

    @Lockable
    public void performBankTransaction(@LockId Account from, Account to)

    would lock on the method using the 'from' field only (and my code knows how to lock based on that).

    I tried doing some searches for this but I'm having a hard time figuring out the correct keywords, as "annotations" / custom AOP etc lead me to all the standard pages.

    Any help would be much appreciated
    Thanks in advance
    AB

  2. #2
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default

    This should be really easy to implement. You need a pointcut such as:
    Code:
    execution(@com.myco.Loackable * *(..))
    and advise it to perform the locking logic.

    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  3. #3

    Default Thanks!

    Thanks! that seems pretty easy, I thought I needed to do some pointcut based on interface name (like *Service) which I didn't particularly like. This is exactly what I wanted.

    Is there any way to get the @LockId parameter annotation inside the interceptor? (I want the instance object that has that annotation).

    Thanks in advance,
    AB

  4. #4
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default

    Getting the argument with @LockId requires the use of reflection. You will need code such as the following:

    Code:
    @Before("lockOperation()")
    public void lock(JoinPoint jp) {
       Method m = ((MethodSignature)jp).getMethod();
       Annotation[][] paramAnnots = m.getParameterAnnotations();
       ... now check which paramAnnot is @LockId, 
       ... that will give you the index, 
       ... then grab the parameter by jp.getArgs()[index]
    }
    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  5. #5

    Default

    Sounds Perfect. I will try it and let the forum know.

    Sincerely,
    AB

  6. #6

    Default ClassCastException

    Apparently I cannot cast the JoinPoint to the MethodSignature interface. I've debugged the code and I'm getting a MethodInvocationProceedingJoinPoint which only implements the ProceedingJoinPoint, JoinPoint.StaticPart interfaces, none of which extends MethodSignature.

    The exact error is
    java.lang.ClassCastException: org.springframework.aop.aspectj.MethodInvocationPr oceedingJoinPoint cannot be cast to org.aspectj.lang.reflect.MethodSignature

    I've been looking at available methods and I cannot find any other that can be used to get the Method class (or actually the @Annotation used in the class).

    As always any help is much appreciated
    Regards
    AB

  7. #7
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default

    I missed getSignagure().. try the following:
    Code:
    Method m = ((MethodSignature)jp.getSignature()).getMethod();
    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  8. #8

    Default

    Worked like a charm, silly me.

    The only issue I had is that this method is an implementation of an interface method, and I'm getting the interface's Method class instead of the implementation ones.

    I eventually did something like this (with pretty formatting)

    jp.getTarget().getClass().getMethod(m.getName(), m.getParameterTypes())

    Thanks for all your help pal
    Regards
    AB

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •