Spring Boot (02) - 元注解
2019-08-28
Coding
Spring Boot
Spring
Java
👋 ‍️‍️阅读
❤️ 喜欢
💬 评论

Spring Boot (02) - 元注解

在Spring Boot中大量使用注解来简化配置。 但是随着注解的增加,重复的注解本身又变得繁琐。

所以Spring Boot定义了新的元注解(Meta-Annotation)结构来简化重复注解的配置。

注意:Spring Boot元注解的定义方式只作用于由Spring Boot框架解析的注解。其他第三方项目的注解不一定使用了这一框架来解析。

注解的组合

现在我们有一组常用的配置,我们需要在很多地方重复定义

@AnnoA("paramA")
@AnnoB(ParamB.class)
class A {
    
}

@AnnoA("paramA")
@AnnoB(ParamB.class)
class B {
    
}

// ... 其他很多地方也有用到

而在Spring Boot中你可以这样定义

@AnnoA("paramA")
@AnnoB(ParamB.class)
@interface MyConfig {
    
}

@MyConfig
class A {
}

@MyConfig
class B {
}

看上去就像是把元注解就地展开

元注解的别名

进一步地,一些注解虽然相似但有时候又不完全相同。这种情况我们没有办法单纯的组合所有注解。

@AnnoA("paramA")
@AnnoB(ParamB.class)
@AnnoC(param = "ConfigForA")
class A {
    
}

@AnnoA("paramA")
@AnnoB(ParamB.class)
@AnnoC(param = "ConfigForB")
class B {
    
}

为此,Spring Boot引入了@AliasFor注解,方便我们在下层注解重写元注解地值。

@AnnoA("paramA")
@AnnoB(ParamB.class)
@AnnoC
@interface MyConfig {
    @AliasFor(annotation = AnnoC.class, attribute = "param")
    String value() default "";
}

@MyConfig("ConfigForA")
class A {
}

@MyConfig("ConfigForB")
class B {
}

注解内别名

除了可以给元注解取别名来覆盖其值,注解内部也可以使用@AliasFor来简化配置用户代码。例如下面的代码

@interface Import{
    String[] basePackageNames() {};
}

@Import(basePackageNames = "a.b.c")
class A{
}

@Import(basePackageNames = "c.b.a")
class B{
}

可以简化为

@interface Import{
    @AliasFor("basePackageNames")
    String[] value() {};
    
    @AliasFor("value")
    String[] basePackageNames() {};
}

@Import("a.b.c")
class A{
}

@Import("c.b.a")
class B{
}

这样用户代码不必再重复写basePackageNames,同时代码又不失可读性。

有趣的是,`@AliasFor`自己本身就用到了`@AliasFor`

小结

Spring Boot使用元注解来简化配置。在Spring Boot提供的注解中,许多都是元注解聚合而来。

一个典型的例子就是入口类的@SpringBootApplication,点开它的源码,看看它是如何聚合的吧。在后文中我们将会一步步了解每一个注解的用法及原理。


Copyright © 2020-2022 Dean Xu. All Rights reserved.