However, from the @Inherited Javadoc:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.
It seems Java ignores annotations on implemented interface method in order to avoid multiple inheritence issues: http://stackoverflow.com/questions/4745798/why-java-classes-do-not-inherit-annotations-from-implemented-interfaces
Now let's consider Spring's @Transactional:
Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactionalannotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.
But Spring Security's @Secured is different. Most the documentation shows the annotation on the interface class methods. In my tests @Secured works on concrete classes and the interfaces and regardless of whether JDK or CGLib proxies are used. This solution appears to be superior to the @Transactional solution. It must reflect not only the methods in question but also discover their interfaces and reflect those, etc, etc... Clearly there's a performance impact, but this seems like a better solution.
Having differing solutions is annoying, confusing and error-prone.
No comments:
Post a Comment