定义高可靠自定义注解需按需组合@Target、@Retention、@Documented及@Inherited/@Repeatable四个核心元注解,属性设计应简洁安全可扩展。
要定义一个标准、高可靠的自定义注解,关键不是堆砌元注解,而是按需组合四个核心元注解,并确保它们逻辑自洽、覆盖完整生命周期与使用边界。缺一不可,但也不应滥用。
@Target + @Retention 是基础骨架
这两个是强制搭配项,缺一无法在运行时生效:
-
@Target 必须明确限定作用位置,比如只用于方法就写
@Target(ElementType.METHOD);若支持类和方法,用数组形式:@Target({ElementType.TYPE, ElementType.METHOD}) -
@Retention 必须设为
RetentionPolicy.RUNTIME,否则反射读不到——几乎所有业务场景(AOP、参数校验、日志增强)都依赖运行时解析
@Documented 增强可维护性
加了它,Javadoc 会把注解本身及其参数说明一起生成到文档中。对团队协作和后期维护很重要,尤其是当注解带多个配置项(如 value()、order()、enabled())时,不加 @Documented 就等于“写了文档却不让人看见”。
@Inherited 和 @Repeatable 按需启用
这两个不是标配,用错反而引入隐患:
- @Inherited 仅对类级注解有效,且子类必须是直接继承才继承注解;接口实现、代理类、泛型类型都不适用。除非你真有“父类配置自动透传给子类”的明确需求,否则不加
-
@Repeatable 需配套定义容器注解(如
@Authorities容纳多个@Authority),适合权限、角色等多值场景。但多数单功能注解(如@Log、@Validated)无需重复,强行加反而增加调用复杂度
属性设计要简洁、安全、可扩展
注解的属性不是越多越好,重点考虑三点:
- 必填项尽量少,优先提供
default值,例如String value() default "";或boolean enabled() default true; - 避免使用复杂类型(如自定义类、集合接口),只允许基本类型、
String、Class、枚举、其他注解或其一维数组 - 命名清晰,避免歧义:比如用
logLevel()而非level(),用skipIfNull()而非ignore()

















