Coming in late to the game, but I provide this for later developers who might stumble across this question.
I would strongly advise against AOP if your application depends on it to operate correctly. Aspects work like this:
- Advice (additional behavior) is applied to
- Join points (places where the extra code can be attached, such a method start or end, or when a given event triggers)
- ... where pointcut (a pattern that detects whether a given join point matches) patterns match
For anyone who's been doing computers for a long time, the fact that patterns are used might be something to look at closely. So to here's an example of a pointcut that matches any method named set
regardless of the arguments:
call(* set(..))
So that's a fairly sweeping pointcut and it should be clear that handling this with care is advised (no pun intended) because you're applying advice to many things.
Or heck, let's apply advice to everything, regardless of name or signature!
execution(* *(..))
So clearly we should be careful because there's a lot of power here, but this is not an argument against aspects — it's an argument for caution because there's a lot of power here and pattern matching can easily go awry (just hit your favorite search engine for aop bugs and have fun).
So here's what looks like a relatively safe pointcut:
pointcut setter(): target(Point) &&
( call(void setX(int)) ||
call(void setY(int)) );
That explicitly provides advice if methods named setX
or setY
on a Point
object are found. The methods can only receive int
s and they must be void
. Looks pretty safe, right? Well, that's safe if those methods exist and you've applied the correct advice. If not, too bad; it silently fails.
To give an example, a friend was trying to debug a Java application where everyone once in a great while, it would return incorrect data. It was an infrequent failure and didn't appear to be correlated with any particular event or data in particular. It was a threading bug, something that is notoriously difficult to test or detect. As it turns out, they were using aspects to lock methods and make them "thread safe", but a programmer renamed a method and a pointcut failed to match it, thus causing a silent breakage of the application.
Thus, I tell people that if they must use AOP, to treat aspects like exceptions: in a well-designed system and if nothing goes wrong, they can be removed and the software still functions correctly. However, if the functionality of the program depends on AOP, you introduce a fragility to your program that is unwarranted.
Thus, logging, debugging and tracing are great examples of behaviors that are perfect for aspects, but security? Nope. Thread safety? Nope.
For a robust alternative to AOP, see traits. Rather than being bolted onto the language, they are integrated into it directly, don't need a "trait aware" IDE (though it can help) and have compile-time failures if the methods you require are not present. Traits do a much cleaner job of handling separation of concerns because the problem was better defined from the start. I use them extensively and they're fantastic.