注解就是貼標簽
(1)注解的作用
1,生成文檔。如常用的@param
2,跟蹤代碼依賴性,實現替代文件的功能。在spring中,主要是減少配置。
3,編譯時進行格式檢查。如常用的@override
(2)注解的分類
1)按照運行機制划分:
【源碼注解→編譯時注解→運行時注解】
源碼注解:只在源碼中存在,編譯成.class文件就不存在了。
編譯時注解:在源碼和.class文件中都存在。像前面的@Override、@Deprecated、@SuppressWarnings,他們都屬於編譯時注解。
運行時注解:在運行階段還起作用,甚至會影響運行邏輯的注解。像@Autowired自動注入的這樣一種注解就屬於運行時注解,它會在程序運行的時候把你的成員變量自動的注入進來。
2)按照來源划分:
【來自JDK的注解——來自第三方的注解——自定義注解】
3)元注解:
元注解是給注解進行注解,可以理解為注解的注解就是元注解。
(3)java中常見的注解
1,JDK的注解
@override標記該方法為覆蓋方法
@Deprecated標記該方法已經過時
@SuppressWarning()表示忽略警告
2,java第三方注解
Spring的注解
@Autowired可以對成員變量、方法和構造函數進行標注,來完成自動裝配的工作
@Service用於標注業務層組件
@Controller用於標注控制層組件(如struts中的action)
@Repository用於標注數據訪問組件,即DAO組件
@Component泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注。
Mybatis的注解
@InserProvider 注解為增加
@UpdateProvider 注解為更新
@Options設置緩存時間
Ps:常用增刪改查:@InsertProvider,@DeleteProvider@UpdateProvider和@SelectProvider
3,元注解
四個元注解分別是:
@Target
@Retention,
@Documented,
@Inherited
元注解是java API提供,是專門用來定義注解的注解,其作用分別如下:
@Target 表示該注解用於什么地方,可能的值在枚舉類 ElemenetType 中,包括:
ElemenetType.CONSTRUCTOR----------------------------構造器聲明
ElemenetType.FIELD --------------------------------------域聲明(包括 enum 實例)
ElemenetType.LOCAL_VARIABLE------------------------- 局部變量聲明
ElemenetType.METHOD ----------------------------------方法聲明
ElemenetType.PACKAGE --------------------------------- 包聲明
ElemenetType.PARAMETER ------------------------------參數聲明
ElemenetType.TYPE--------------------------------------- 類,接口(包括注解類型)或enum聲明
@Retention 表示在什么級別保存該注解信息。可選的參數值在枚舉類型 RetentionPolicy 中,包括:
RetentionPolicy.SOURCE ---------------------------------注解將被編譯器丟棄
RetentionPolicy.CLASS -----------------------------------注解在class文件中可用,但會被VM丟棄
RetentionPolicy.RUNTIME VM-------將在運行期也保留注釋,因此可以通過反射機制讀取注解的信息。
@Documented 將此注解包含在 javadoc 中 ,它代表着此注解會被javadoc工具提取成文檔。在doc文檔中的內容會因為此注解的信息內容不同而不同。相當與@see,@param 等。
@Inherited 允許子類繼承父類中的注解。
4,自定義注解
例子:
定義:
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented public @interface Description {
String desc();
String author();
int age() default 18;
}
測試:
@Description(desc="i am Color",author="boy",age=18)
public String Color() {
return "red";
}
因為我們前面定義的作用域是在方法和類接口上,所以這個注解在Color()方法上使用是沒問題的
使用自定義注解:
使用注解的語法:
@<注解名>(<成員名1>=<成員值1>,<成員名1>=<成員值1>,...)
案例:
@Description(desc="i am Color",author="boy",age=18)
public String Color() {
return "red";
}
這里的Description是我們剛才在自定義注解語法要求里面定義的注解噢,然后我們可以給它的每一個成員變量賦值,注意數據類型。值得注意的是,因為我們前面定義的作用域是在方法和類接口上,所以這個注解在Color()方法上使用是沒問題的。
解析注解
概念:
通過反射獲取類 、函數或成員上的運行時注解信息,從而實現動態控制程序運行的邏輯。
實例:
1、創建@Table注解 package person.lb.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 表名 * @author nobounds * */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Table { String value() default ""; } 2、創建@Column注解: package person.lb.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 字段 * @author nobounds * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String name() default ""; String dataType() default "varchar(20)"; String comment() default ""; } 3、創建實體類Users: package person.lb.annotation; @Table("users") public class Users { @Column(name="ID", dataType="int") private int id; @Column(comment="用戶名") private String userName; @Column(name="pwd", comment="密碼") private String password; @Column(dataType="varchar(25)", comment="郵箱") private String email; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } 4、創建注解處理器AnnotationHandler: package person.lb.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Field; public class AnnotationHandler { public static void main(String[] args) { StringBuilder sql = new StringBuilder("CREATE TABLE "); try { Class clazz = Class.forName("person.lb.annotation.Users"); //獲取Users類上的Table注解 Table tableAnnotation = (Table) clazz.getAnnotation(Table.class); //獲取表名 String tableName = tableAnnotation.value().toUpperCase(); if("".equals(tableName)) { tableName = clazz.getName().toUpperCase(); } sql.append(tableName); sql.append(" ( \n"); //獲取類中的所有字段 Field[] fields = clazz.getDeclaredFields(); for(Field field : fields) { //獲取字段上的所有注解 Annotation[] fieldAnnotations = field.getAnnotations(); if(fieldAnnotations.length > 0) { //遍歷注解 for(Annotation fieldAnnotation : fieldAnnotations) { //如果是@Field注解,那么進行處理 if(fieldAnnotation instanceof Column) { //獲取字段名 String columnName = ((Column) fieldAnnotation).name().toUpperCase(); if("".equals(columnName)) { columnName = field.getName().toUpperCase(); } //獲取數據類型 String dataType = ((Column) fieldAnnotation).dataType().toUpperCase(); //獲取注釋 String comment = ((Column) fieldAnnotation).comment(); if("".equals(comment)) { sql.append(columnName + "\t" + dataType + ",\n"); } else { sql.append(columnName + "\t" + dataType + " COMMENT '" + comment + "',\n"); } } } } } sql.append(" ) "); System.out.println("生成的sql語句為:\n" + sql.toString()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
結果:
生成的sql語句為: CREATE TABLE USERS ( ID INT, USERNAME VARCHAR(20) COMMENT '用戶名', PWD VARCHAR(20) COMMENT '密碼', EMAIL VARCHAR(25) COMMENT '郵箱', )