I have a field set pointcut, which seems to do as I expect. Its defined as follows
before(Object newval): set(@Serviced private * *.*) && args(newval)
The above is meant to capture: whenever a private field attribute, annotated with @Serviced, is set call my before advice.
Everything seems to work fine, except for the one case in my code that sets a variable matching the above via java reflection ( ie via java.lang.reflect.Field.set(....).
Any idea's how I can catch that "set" also?
Thanks
As you have noticed, the
set()
pointcut cannot intercept reflective field changes. But if you control (i.e. can weave aspects into) the code calling theField.set*(..)
methods, you can work around that issue by also using reflection. Here is a complete, compileable code sample illustrating the solution:Sample annotation:
Sample entity class with main method:
As you can see, only two out of three private fields have the
@Serviced
annotation. Setters are called for all three fields twice: once normally and once via reflection.Aspect intercepting both normal and reflective field changes:
Sample output when running
Person.main
:The output clearly shows that both advice only "do something" (in this case print information to standard output) for fields annotated with
@Serviced
, whereas other fields are skipped. While theset()
pointcut applies statically, the reflective one needs to determine if the target field has a matching annotation dynamically.