1. 注解(Annotation)
- JDK1.5 以后版本引入的一個(gè)特性
- 可以被其他程序(比如:編譯器)讀取
- 語(yǔ)法
@注釋名
2. 內(nèi)置注解
- @Override
- 標(biāo)記重寫父類方法
- @Deprecated
- 標(biāo)記過(guò)時(shí)方法宅楞,表示不建議再使用
- @SuppressWarnings
- 抑制編譯時(shí)的警告信息
- 需要添加參數(shù)才能正常使用,例如
@SuppressWarnings("unchecked")
3. 元注解(meta-annotation)
- 作用:注解其他注解
- 定義了 4 個(gè)標(biāo)準(zhǔn)的 meta-annotation 類型袱吆,用來(lái)對(duì)其他類型作說(shuō)明
- @Target
- @Retention
- @Documented
- @Inherited
3.1 @Target
- Indicates the contexts in which an annotation type is applicable
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE
}
3.2 @Retention
- 描述注解的生命周期
- SOURCE < CLASS < RUNTIME
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
public enum RetentionPolicy {
// 保留在源碼階段厌衙,編譯時(shí)被丟棄
SOURCE,
// 保留到編譯進(jìn)行時(shí)的class文件,但 JVM 加載class文件時(shí)候被遺棄
CLASS,
// 保留到程序運(yùn)行時(shí)
RUNTIME
}
3.3 @Documented
- 將被記錄在 javadoc 中
3.4 @Inherited
- 子類可以繼承父類的注解
4. 自定義注解
- 定義注解用 @interface, 注解中只能包含屬性
- 里面的方法實(shí)際上是聲明的屬性绞绒,方法名稱就是屬性名稱婶希,返回值類型就是屬性的類型
- 若只有一個(gè)屬性,一般名為 value
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EntryLog {
// 屬性 value
String value() default "";
String[] codes() default {};
}
若屬性沒(méi)有默認(rèn)值蓬衡,必須給注解賦值
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EntryLog {
String value() default "";
String[] codes();
}
// 需給注解賦值
@EntryLog(codes = {"1001", "1002"})
4.1 注解屬性類型
- 基本數(shù)據(jù)類型
- String 類型
- Class 類型
- 枚舉類型
- 注解類型
- 以上類型的一維數(shù)組
數(shù)組用 {} 來(lái)存儲(chǔ)喻杈,當(dāng)數(shù)組中只有一個(gè)值時(shí)可省略 {}
// 數(shù)組類型 String[] codes();
@EntryLog(codes = "1001")
@EntryLog(codes = {"1001", "1002"})
// 枚舉數(shù)組類型 ElementType[] value();
@Target(ElementType.TYPE)
@Target({ElementType.TYPE, ElementType.METHOD})
4.2 反編譯文件
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface EntryLog {
int num() default 0;
String value();
// Class 類型
Class<?> clazz();
// 枚舉類型
CodeEnum codeEnum();
// 注解類型
DemoAnno demoAnno();
}
// 自動(dòng)繼承 java.lang.annotation.Annotation 接口
public interface EntryLog extends java.lang.annotation.Annotation {
public abstract int num();
public abstract java.lang.String value();
public abstract java.lang.Class<?> clazz();
public abstract com.example.concrete.CodeEnum codeEnum();
public abstract com.example.concrete.DemoAnno demoAnno();
}
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
5. Spring 注解 @AliasFor
- @AliasFor 用于聲明注釋屬性別名
同一個(gè)注解中的兩個(gè)屬性互為別名
例如:@ComponentScan 注解中,value 和 basePackages 兩個(gè)屬性互為別名
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
}
跨注解的屬性別名
例如:@Service#value的值可以映射到@Component#value
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
public @interface Component {
String value() default "";
}
5.1 @SpringBootApplication 分析
public @interface SpringBootApplication {
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
}
其他
- Java注解是使用動(dòng)態(tài)代理類實(shí)現(xiàn)
- 可以通過(guò)反射機(jī)制實(shí)現(xiàn)對(duì)元數(shù)據(jù)的訪問(wèn)
- SpringBoot深入理解 -- @AliasFor注解的作用