JDK提供的@Repeatable注解的作用

我们都知道,在一个方法/类/字段上,对于同一个注解,只能添加一个,如果添加重复的注解,那么就会出现如下这样的错误。

我们都知道,在一个方法/类/字段上,对于同一个注解,只能添加一个,如果添加重复的注解,那么就会出现如下这样的错误。

image.png

那么我们如何实现在一个类上标注多个相同注解?其实有一种方式,比如我们的ComponentScan注解和@ComponentScans注解。在@ComponentScans中定义一个value,类型为ComponentScan[],这样就可以在@ComponentScan注解上配置一个数组,从而间接实现一个类上标注多个注解。如下

public @interface ComponentScans {
    public ComponentScan[] value();
}

但是这其实并不是真正的标注了相同的注解,在使用时还是标注了别的注解,而不是直接标注了多个@CompoentScan。但是其实JDK为我们考虑了这种需要,为我们提供了java.lang.annotation.Repeatable这个注解,就是为了帮我们实现这个需求的。

这个注解需要将原来配置的@ComponentScan注解上加上@Repeatable注解,指定如果出现了多个注解,将会被合成到哪个注解内。

@Repeatable(ComponentScans.class)  // 使用@Repeatable注解,如果重复使用@ComponentScan注解,将会被合成成为一个一个@ComponentScans注解
public @interface ComponentScan {
    public String[] value() default {};
}

image.png

配置了该配置之后,我们发现不再报错了!完全可以使用重复的注解了,但是在编译时,编译器会帮我们把多个@CompoentScan注解,合成给一个@ComponentScans注解。

需要注意的是,合成这个词,我们下来来进行验证一下。

验证代码如下

@ComponentScan
@ComponentScan
public class App {

    public static void main(String[] args) throws Exception {
        Annotation[] annotations = App.class.getAnnotations();
        System.out.println(annotations.length);
        System.out.println(Arrays.toString(annotations));
    }
}

最终得到的结果如下,验证我们的结论,在运行时所有的@ComponentScan注解都被合并到@ComponentScans注解当中去。

1
[@com.wanna.ComponentScans(value={@com.wanna.ComponentScan(value={}), @com.wanna.ComponentScan(value={})})]
Comment