What does the syntax `@__()` mean in Lombok?

This is an experimental Lombok syntax, created to support a layer of indirection when referencing multiple annotations, rather than use a Class<?>[].

The syntax is a little strange; to use any of the 3 onX features, you must wrap the annotations to be applied to the constructor / method / parameter in @__(@AnnotationGoesHere). To apply multiple annotations, use @__({@Annotation1, @Annotation2}). The annotations can themselves obviously have parameters as well.

https://projectlombok.org/features/experimental/onX.html

An explanation from Lombok developer Roel Spilker:

The reason for it is that javac already resolves annotations in the parsing phase, and gives errors if it can determine that the annotations are invalid. By using a non-existent annotation @__ it cannot determine it is bogus (it might be created by an annotation processor) and will not give an error right away. That gives Lombok the time to do its work and remove the @__ from the code.


It means that the generated constructor (not controller) will also have the @Autowired annotation added to it so that spring can do its magic. With lombok you can write your code like

@RequiredArgsConstructor(onConstructor=@__(@Autowired(required=true)))
public class FooController {
    private final FooService service;
    interface FooService {}
}

and lombok will convert it during compilation to

public class FooController {
    private final FooService service;
    @Autowired(required=true)
    public FooController(FooService service) {
        this.service = service;
    }
}

@__ is used to overcome the type limitations of annotations because

@interface MultipleAnnotations {
    Annotation[] value();
}

does not work because the supertype of all annotations is itself not an annotation and

@interface MultipleAnnotations {
    Class<? extends Annotation>[] value();
}

does not allow parameters in annotations: @MultipleAnnotations(SomeAnnotation.class)


For JDK8 users who are confused about this weird syntax, there is a little bit cleaner way as mentioned here - On javac8 and up, you add an underscore after onMethod, onParam, or onConstructor.

So it will change from @RequiredArgsController(onController = @__(@Autowired)) to @RequiredArgsController(onController_ = @Autowired)

Tags:

Java

Lombok