注解就是貼標簽
(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 '郵箱', )
