How to extend Java annotation?

前端 未结 6 1207
闹比i
闹比i 2020-12-09 01:08

In my project I use pre-defined annotation @With:

@With(Secure.class)
public class Test { //....

The source code of @Wit

相关标签:
6条回答
  • 2020-12-09 01:37
    @With(Secure.class)
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Secure {
    
    }
    

    This will work.

    0 讨论(0)
  • 2020-12-09 01:38

    As piotrek pointed out, you cannot extend Annotations in the sense of inheritance. Still, you can create Annotations that aggregate others:

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    public @interface SuperAnnotation {
        String value();
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    public @interface SubAnnotation {
        SuperAnnotation superAnnotation();
        String subValue();
    }
    

    Usage:

    @SubAnnotation(subValue = "...", superAnnotation = @SuperAnnotation(value = "superValue"))
    class someClass { ... }
    
    0 讨论(0)
  • 2020-12-09 01:43

    To expand on Muhammad Abdurrahman's answer--

    @With(Secure.class)
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Secure {
    
    }
    

    This does not work by default but you can use it in conjunction with Spring's AnnotationUtils.

    See this SO answer for an example.

    0 讨论(0)
  • 2020-12-09 01:48

    You can use annotation for annotation like this:

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    @WithSecurityContext(factory = WithCustomUserSecurityContextFactory.class)
    public @interface WithCustomUser {
      String username() default "demo@demo.com";
      String password() default "demo";
      String[] authorities() default {Authority.USER};
    }
    

    And define exact state in its "child"

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    @WithCustomUser(username = "admin@admin.com",
                    password = "admin",
                    authorities = {Authority.USER, Authority.ADMINISTRATOR})
    public @interface WithAdminUser {
    }
    

    In this case you have a some kind of "state" and access to the parent annotation fields via reflection/aspect.

    0 讨论(0)
  • 2020-12-09 01:49

    From Java language specification, Chapter 9.6 Annotation Types:

    No extends clause is permitted. (Annotation types implicitly extend annotation.Annotation.)

    So, you can not extend an Annotation. you need to use some other mechanism or create a code that recognize and process your own annotation. Spring allows you to group other Spring's annotation in your own custom annotations. but still, no extending.

    0 讨论(0)
  • 2020-12-09 01:58

    So the provided answer from Eric Jiang is 100% working in my situation and she is: I need JMSListener ,but i want to hide the destination name:

    @GetPlayerDataByUUIDListener
        public void getPlayerDataByUUID(Object message) {
            System.out.println("Im Here");
        }
    

    `

    @JmsListener(destination = PlayerStatisticsJMSConstants.GET_PLAYER_DATA_BY_UUID)
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface GetPlayerDataByUUIDListener {
    }
    

    So this is working perfectly ,and it is the same as:

    @JmsListener(destination = "example")
        @GetPlayerDataByUUIDListener
        public void getPlayerDataByUUID(Object message) {
            System.out.println("Im Here");
        }
    
    0 讨论(0)
提交回复
热议问题