Skip to content
This repository was archived by the owner on Dec 23, 2020. It is now read-only.

t1/power-annotations

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Power-Annotations !!! ARCHIVED !!!

Note
This project has moved to MP GraphQL

Instead of SuperHero.class.getAnnotation(Entity.class), use Annotations.on(SuperHero.class).get(Entity.class) and you’ll get some very powerful features described below. This works also for fields and methods; simply use Annotations.onField or Annotations.onMethod.

Fields and methods don’t have to be declared directly on the target class or interface, but can be inherited from some super class or interface. All annotations work as if the field was on the sub type.

Features

Jandex

If there is a Jandex index file, all annotations will be read from there.

A Jandex file is advisable but optional, i.e. if there is no Jandex file, Power-Annotations will fall back to scan the classpath with JDK reflection, slowing down startup time. As this also means that a lot of classes from all dependencies have to be scanned, this can have a severe performance impact. If you want to stay dynamic but exclude some dependencies, you can do so by adding a file META-INF/jandex.properties with a property exclude containing a space-delimited list of artifactId:groupId. See implementation/src/main/resources/META-INF/jandex.properties.

Inheritance

When annotating a super class or interface, the annotation is valid also for the sub class or interface. This is also true for annotations on overridden or implemented methods.

In Java reflection, this only works for super classes and only if the annotation is annotated as @Inherited. As this generally violates the LSP, power-annotations always resolves these annotations. We may add a mechanism to not inherit annotations later, if the need actually arises.

Stereotypes

The simplest use-case for Stereotypes is renaming annotations, e.g. @Property instead of @JsonbProperty (assuming your JBON-B implementation supported Power Annotations).

@Retention(RUNTIME)
@Stereotype
@JsonbProperty
public @interface Property {}

It gets much more interesting, when you add more annotations from other (supporting) frameworks to your stereotype, e.g. @XmlAttribute from JAX-B. Now you have one annotation instead of two with both having the same semantics.

Properly used, stereotypes are shortcuts describing the role the annotated element has; functionally as well as a documentation.

This is exactly what CDI-Stereotypes do, but not restricted to CDI, i.e. the annotations used by any framework that supports Power Annotations can be used with stereotypes. We have our own Stereotype class; but as we don’t want to depend on CDI and still not exclude CDI, any annotation named Stereotype will work.

Resolve From Class

This is a very common pattern: annotations on a class are considered as a fallback for member annotations (i.e. on fields or methods), if

  • the member is not annotated with the same type or the annotation is repeatable, and

  • the annotation is annotated to be an explicitly allowed @Target for FIELD/METHOD.

Mixins

Say you have a class you want to add annotations to, but you can’t; e.g., because it’s a class from some library or even from the JDK. You can create your own class (or interface) and annotate it as @MixinFor the target class. The annotations you put on your mixin class will work as if they were on the target class (if your framework supports Power Annotations).

This also works for annotations: say we’re developing an application packed with annotations from JPA, which doesn’t support mixins (yet). The application also uses a library that supports mixins but doesn’t know about JPA, e.g. a future MP GraphQL. We want all JPA @Id annotations to be recognized as synonyms for GraphQL @Id annotations. We could create a simple mixin for the JPA annotation:

@MixinFor(javax.persistence.Id.class)
@org.eclipse.microprofile.graphql.Id
public class PersistenceIdMixin {}

Voila! MP GraphQL would work as if all JPA @Id annotations were it’s own.

Note
Mixins are a very powerful kind of magic: use them with caution and only when strictly necessary. Otherwise, the readers of your code will have a hard time to find out why something behaves as if an annotation was there, but it’s clearly not. If you can, use Stereotypes instead.

About

Annotations with Super-Powers

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages