Что означает синтаксис `@__ ()` в Ломбоке?

Я работаю и активно использую Lombok 2 месяца. С Java я немного лучше знаком. Но впервые я столкнулся со следующей структурой синтаксиса в языке:

@RequiredArgsController(onController = @__(@Autowired))
                                       ^^^

Что это значит и как это компилируется?


person Andrew Tobilko    schedule 27.06.2016    source источник
comment
Немного покопавшись, это удалось: projectlombok.org/features/experimental/onX.html: < i> тип @__ - это ссылка на аннотацию типа __ (двойное подчеркивание), которого на самом деле не существует. Хотя я ничего не знаю о Ломбоке. (также это письмо)   -  person Tunaki    schedule 27.06.2016


Ответы (3)


Это экспериментальный синтаксис Lombok, созданный для поддержки уровня косвенного обращения при ссылке на несколько аннотаций вместо использования Class<?>[].

Синтаксис немного странный; чтобы использовать любую из 3 onX функций, вы должны заключить аннотации, которые будут применяться к конструктору / методу / параметру, в @__(@AnnotationGoesHere). Чтобы применить несколько аннотаций, используйте @__({@Annotation1, @Annotation2}). Аннотации, очевидно, тоже могут иметь параметры.

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

Объяснение от разработчика Lombok Роула Спилкера:

Причина в том, что javac уже разрешает аннотации на этапе синтаксического анализа и выдает ошибки, если он может определить, что аннотации недействительны. Используя несуществующую аннотацию @__, он не может определить, что это подделка (она может быть создана обработчиком аннотаций), и не сразу выдаст ошибку. Это дает Lombok время выполнить свою работу и удалить @__ из кода.

person OrangeDog    schedule 27.06.2016
comment
Причина в том, что javac уже разрешает аннотации на этапе синтаксического анализа и выдает ошибки, если он может определить, что аннотации недействительны. Используя несуществующую аннотацию @__, он не может определить, что это подделка (она может быть создана обработчиком аннотаций), и не сразу выдаст ошибку. Это дает Lombok время выполнить свою работу и удалить @__ из кода. - person Roel Spilker; 28.06.2016

Это означает, что сгенерированный конструктор (не контроллер) также будет иметь аннотацию @Autowired, чтобы Spring мог творить чудеса. С помощью ломбока вы можете написать свой код как

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

и lombok преобразует его во время компиляции в

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

@__ используется для преодоления ограничений типа аннотаций, потому что

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

не работает, потому что супертип всех аннотаций сам по себе не является аннотацией и

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

не допускает параметров в аннотациях: @MultipleAnnotations(SomeAnnotation.class)

person zapl    schedule 27.06.2016
comment
Можно было просто использовать Class[] и проверять isAnnotation() во время компиляции. - person OrangeDog; 27.06.2016
comment
@OrangeDog, который не разрешает параметры в аннотациях - person zapl; 27.06.2016
comment
Команда ломбока представила предложение, чтобы добавить возможности для аннотации [] в аннотации, но оно было отклонено . Может, когда-нибудь мы его возродим ... - person Roel Spilker; 28.06.2016

Для пользователей JDK8, которых смущает этот странный синтаксис, есть более чистый способ, как упоминалось здесь - On javac8 and up, you add an underscore after onMethod, onParam, or onConstructor.

Таким образом, он изменится с @RequiredArgsController(onController = @__(@Autowired)) на @RequiredArgsController(onController_ = @Autowired)

person sinujohn    schedule 06.01.2020
comment
я думаю, что это @RequiredArgsConstructor (onConstructor_ = @Autowired), а не @RequiredArgsController - person Krishna; 15.10.2020