簡體   English   中英

如何讓自定義注解繼承其他注解

[英]How to make a custom annotation inherit other annotations

我為自定義數據類型創建了自定義注釋。 目前我的實體看起來像這樣:

@Entity
public class contact {

    @Valid
    @Randomizer(EmailAddressValidator.class)
    @EmailAddressField
    @Convert(converter = EmailAddressConverter.class)
    @JsonSerialize(using = EmailAddressSerializer.class)
    @Column(name = "email")
    private EmailAddress email;
}

但我想有以下內容

@Entity
public class contact {

    @EmailAddressField
    @Column(name = "email")
    private EmailAddress email;
}

我必須在我自己的注釋中做什么,這樣我就不必為每個屬性編寫其他注釋?

為了清楚起見,我想把所有東西都放在一起,只需要給屬性寫一個注釋。

我的注釋目前看起來像這樣:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE_USE})
@Constraint(
    validatedBy = {EmailAddressValidator.class}
)
@Documented
public @interface EmailAddressField {
    Class<?>[] groups() default {};

    String message() default "No Email Address";

    Class<? extends Payload>[] payload() default {};
}

但是,如果我將其更改為此,它就不起作用:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE_USE})
@Constraint(
    validatedBy = {EmailAddressValidator.class}
)
@Documented
// -- Annotations from property
@Valid
@Randomizer(EmailAddressValidator.class)
@Convert(converter = EmailAddressConverter.class)
@JsonSerialize(using = EmailAddressSerializer.class)
@Inherited
// --
public @interface EmailAddressField {
    Class<?>[] groups() default {};

    String message() default "No Email Address";

    Class<? extends Payload>[] payload() default {};
}

Java 注釋是可以應用於方法、類和字段的接口,它們不能將其他注釋作為值,因為它們不是對象,它們是一種沒有任何方法或狀態的元數據形式,它們的主要目的是提供可以被其他工具讀取和處理的元數據,例如 Java 編譯器或 JVM。

避免編寫以下樣板代碼的一個可能解決方案是創建一個自定義注釋處理器,它使用來自javax.annotation.processing packageAbstractProcessor class class。 這將允許您定義自定義注釋並指定在編譯期間在代碼中遇到它們時應采取的操作。

這是文檔; https://docs.oracle.com/en/java/javase/11/docs/api/java.compiler/javax/annotation/processing/Processor.html https://docs.88414252950/enjava/88.com /11/docs/api/java.compiler/javax/annotation/processing/AbstractProcessor.html

在gradle添加如下依賴,用於配置@AutoService

dependencies {
    annotationProcessor 'com.google.auto.service:auto-service:1.0-rc5'
    compileOnly 'com.google.auto.service:auto-service:1.0-rc5'
}

這是示例代碼;

@AutoService(Processor.class)
@SupportedAnnotationTypes("com.example.EmailAddressField")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class EmailAddressFieldProcessor extends AbstractProcessor {

    private Elements elementUtils;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        this.elementUtils = processingEnv.getElementUtils();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (TypeElement annotation : annotations) {
            for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
                if (element.getKind() == ElementKind.FIELD) {
                    VariableElement field = (VariableElement) element;
                    AnnotationMirror validAnnotation = elementUtils.getAnnotationMirror(Valid.class);
                    field.getAnnotationMirrors().add(validAnnotation);
                    AnnotationMirror convertAnnotation = elementUtils.getAnnotationMirror(Convert.class);
                    field.getAnnotationMirrors().add(convertAnnotation);
                    // BlahBlah.class annotation..... etc...
                }
            }
        }
        return true;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM