Pointcuts by annotations
Using annotations is more convenient than using patterns. While patterns might be anything between a big cannon and a scalpel the annotations are definitely a scalpel, by only getting the pointcuts that the developer has manually specified.
You can get the code for this blog series at the Git repository here.
Let’s start coding!
Requirements: Maven, Java 8, (preferably) an IDE (I’m using IntelliJ)
The use of annotations is a precise way to define when an aspect should be run. They are only run when a developer has used the annotation on an object or method.
The errors that can and will occur
Using only annotations creates another problem that we don’t need to think about while using patterns; It will make our advice run twice(or more), because the annotation pointcut don’t specify if it should be run during execution or initialization. The reason for the advice in the pattern example not being executed twice is that the pattern uses the combinator execute(pattern) . We are practically saying that the advice should only look for code that’s executed. There are different combinators that we can use to define when we should run our advice; one of them is execute.
So instead of only using annotations we need to use annotations and a combinator with a pattern. The simplest way is to use a catch all pattern with the combinator execution and then combine it with an annotation.
A real example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
In this example we are using the combinator execute with a catch-all pattern and annotations. Basically we are looking for any code that’s executed and has the annotation @YourAnnotation. There is a whole list of different combinators at AspectJ’s homepage. Each one of them can take different patterns to help you define when your advice should be triggered.
Implementing annotation in a class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
By adding the @YourAnnotation
before any method the aspect will find the annotation and execute the advice body.
Complexity and @Pointcut
When there is a need to define pointcuts that are a bit more complex we can define a standalone pointcut that we can reuse. By using the @Pointcut attribute we can define a specific pointcut and when it should get run. We can then use the name of the pointcut as a reference in the @Before , @After, @AfterThrowing, @AfterReturn and @Around .
A real example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
We got the same result as the earlier example but we are using the name of the pointcuts so we can reuse them.
Conclusion
Annotations can be a precise tool, as a pointcut will not trigger if the annotations are not in the code. But there are some weak points that we need to try and cover up with the use of combinators and patterns. Combining patterns and annotations is a good middle road when we want to specify when the advice should be run.