如何扩展Java注释?

时间:2014-03-02 11:16:31

标签: java annotations

在我的项目中,我使用预定义的注释@With

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

@With的源代码:

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

    Class<?>[] value() default {};
}

我想编写自定义注释@Secure,其效果与@With(Secure.class)相同。怎么做?


如果我这样喜欢怎么办?它会起作用吗?

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

}

6 个答案:

答案 0 :(得分:17)

来自Java语言规范,Chapter 9.6 Annotation Types

  

不允许使用扩展条款。 (注释类型隐式扩展annotation.Annotation。)

因此,您无法扩展Annotation。您需要使用其他一些机制或创建识别和处理您自己的注释的代码。 Spring允许您在自己的自定义注释中对其他Spring的注释进行分组。但仍然没有延伸。

答案 1 :(得分:16)

正如piotrek指出的那样,你不能在继承意义上扩展注释。您仍然可以创建聚合其他人的注释:

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

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

用法:

@SubAnnotation(subValue = "...", superAnnotation = @SuperAnnotation(value = "superValue"))
class someClass { ... }

答案 2 :(得分:5)

e.preventDefault();

这样可行。

答案 3 :(得分:3)

扩展Muhammad Abdurrahman的答案 -

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

}

默认情况下有效,但您 可以将其与Spring的AnnotationUtils结合使用。

有关示例,请参阅this SO answer

答案 4 :(得分:1)

您可以像这样使用注释注释:

@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};
}

在&#34; child&#34;

中定义准确状态
@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 {
}

在这种情况下,你有某种状态&#34;状态&#34;并通过反射/方面访问父注释字段。

答案 5 :(得分:0)

因此,在我的情况下,埃里克·江(Eric Jiang)提供的答案是100%可行的,她是: 我需要JMSListener,但我想隐藏目标名称:

@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 {
}

因此,它运行良好,并且与:

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