I've said many times that I think annotations are a lot like AOP. AOP is great, but I don't believe application developers should be writing their own aspects. They should be making use of the aspects provided by framework developers. (As a side note, annotations are the best way I've seen to apply apply aspects) Similarly, developers should embrace the use of annotations wholeheartedly, but in general they should be using annotations created by framework developers and not creating their own application-specific annotations.
The reasoning behind that is that annotations (I'm referring primarily to runtime annotations here) need to be processed by something to have meaning. No framework is going to be able to attach useful meaning to a user-defined annotation, so user-defined annotations imply user-defined annotation processing code. I don't like the idea of that at all, so it's been quite easy to say annotation definitions should strictly be the domain of framework developers.
The flaw in the argument is rather obvious now. I stand by the assertion that application developers should not be writing annotation processing code. However, it's simply not true that user-defined annotations imply custom processing code.
The key to this is the meta-annotation. An annotation definition itself can be annotated in a way that tells the annotation processor how to deal with it. A simple example of this is a Hibernate validation annotation. Here's a validation annotation I wrote before Hibernate validator had the @Digits annotation. The @ValidatorClass annotation alerts Hibernate validator to pay attention the @Digits and defines what how the framework should interpret the annotation.
@ValidatorClass(DigitsValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Digits {
int integerDigits();
int fractionalDigits() default 0;
String message() default "invalid numeric value";
}
I've generally assumed meta-annotations would be the exception rather than the rule, but Web Beans has turned that assumption upside down. In Web Beans, it will be quite common for application developers to write meta-annotations for interactions with almost every part of the framework. Here's a quick example from Gavin's Web Beans Sneak Peak series. A type-safe injection point might look like the following:
@In defines this as an injection point, and @PayByCheque is a user-defined annotation that defines what type of injection is to occur. Here's the definition:
@BindingType
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD})
public @interface PayByCheque {}
You might be wondering what is going on here. @BindingType is the meta annotation that tells Web Beans that this is annotation marks a binding type, but where is the information that tells Web Beans how specifically to deal with this annotation? For that, we have to look at the corresponding component definition.
@Component @PayByCheque
public class ChequePaymentProcessor implements PaymentProcessor {
public void process(Payment payment) { ... }
}
One the injection side, the user-defined annotation is paired with @In. On the component declaration side, it is paired with @Component. The annotation provides the link between the points. Compare this to the current version of Seam (or Web Beans using named components) where this binding is done by a textual name. It might seem that annotations are just a unnecessarily complex replacement for a text string, albeit one that is much friendlier to refactoring and side-steps the messy name collision and namespace issues that you get with plain strings. But, actually Web Beans allows annotations to be combined in very interesting ways. Again, an example:
@In @Asynchronous @PayByCheque paymentProcessor;
Here, @Asynchronous is a user-definied annotation that is combined with @PayByCheque to uniquely reference a Web Bean. I think this is particularly clever because it eliminates name mangling and turns the name modifiers into language constructs that can re-used throughout a system.
If you look closely at the Web Beans draft, you'll see the concept permeates through Web Beans in a surprisingly diverse set of ways. It's enough to convince me that user-defined annotations really are useful and that application developers probably will be regularly defining their own annotations.