One of the things I have the most trouble with though is ensuring that my joinpoint definitions stay up to date as my code changes. I've mostly worked with aspectjweaver and generally define the joinpoints in my aop.xml file. But say I have a joinpoint that applies advice at some method doX. Now someone refactors doX and calls it doY. I know aspectjweaver will print out a warning but is there any way to enforce this at compile time to ensure I'm not defining joinpoints that match nothing? Or even better any IDE tools to refactor the joinpoint as the method is refactored? Any tips on how to deal with this would be appreciated.
One way to keep join point selection stable is to use only stable characteristics of program elements: base interfaces, accepted naming conventions, declared exceptions etc. However, in certain cases such as transaction management and security, finding stable inherent characteristics can become difficult. This is where annotations come into picture. The use of annotations require that classes collaborate with aspects, but in the end, it gives a much simpler and stable solution.
Thanks for the quick answer. I did have a follow-up to this if you wouldn't mind.
One way to keep join point selection stable is to use only stable characteristics of program elements: base interfaces, accepted naming conventions, declared exceptions etc
This makes perfect sense, and I try to do that when possible.
However, in certain cases such as transaction management and security, finding stable inherent characteristics can become difficult. This is where annotations come into picture. The use of annotations require that classes collaborate with aspects, but in the end, it gives a much simpler and stable solution.
Could you expand on this a little more? Which annotations are you referring to here?
Joined: Jul 23, 2003
Any annotations: external and internal frameworks and custom annotations. For example, if you wanted to apply a retry logic, you could devise @Idempotent as a custom annotation and use execution(@Idempotent * *(..)) to select such operations. In a similar way, you can use @Transaction (Spring), @Secured (Spring Security), @Entity (JPA) etc. Please see my articles (http://www.ibm.com/developerworks/java/library/j-aopwork3 and http://www.ibm.com/developerworks/java/library/j-aopwork4) for more details -- but these are somewhat older articles so some information has changed since their publication.
Joined: Apr 07, 2007
Good stuff here. I never really thought about using annotations with AOP. I've written custom annotations for other things (such as automatically registering an object as a listener and invoking an annotated method). Although it makes perfect sense since I'd guess that's how the transactional annotations work. One example that comes to mind is for logging. I could annotate something with @Logged and automatically log the input parameters for example (if I was interested in that).
Using AOP outside of Spring (aspectjweaver) seems like it would work well too so I don't need to rely on spring beans (I'm assuming Spring AOP only intercepts beans - I mistakenly said I've used mostly Spring AOP but since corrected that to non-spring AOP), rather I can intercept the class when it is loaded, whether through spring or not.