最近忽然看到其餘人寫的代碼實現了自定義註解,好奇心被激活了。因此查了不少資料,而後寫了一個簡單的自定義註解,在寫的過程當中我發現了調用自定義註解的麻煩,因此我但願把個人代碼貼出來,而後但願各位大牛們可以幫我簡化調用過程。java
自定義的註解實現,主要是經過建立註解類,添加元註解,使用反射調用這幾步。spring
其中反射的調用比較活,因此要更具實際狀況來進行編寫代碼 。ide
下面就介紹一下我寫的自定義註解吧。工具
元註解:元註解的做用就是負責註解其餘註解。Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它 annotation類型做說明。Java5.0定義的元註解:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited
這些類型和它們所支持的類在java.lang.annotation包中能夠找到。下面咱們看一下每一個元註解的做用和相應分參數的使用說明。this
@Target:.net
@Target說明了Annotation所修飾的對象範圍:Annotation可被用於 packages、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數)。在Annotation類型的聲明中使用了target可更加明晰其修飾的目標。對象
做用:用於描述註解的使用範圍(即:被描述的註解能夠用在什麼地方)繼承
取值(ElementType)有:接口
1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述域
3.LOCAL_VARIABLE:用於描述局部變量
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述參數
7.TYPE:用於描述類、接口(包括註解類型) 或enum聲明生命週期
@Retention:
@Retention定義了該Annotation被保留的時間長短:某些Annotation僅出如今源代碼中,而被編譯器丟棄;而另外一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,而另外一些在class被裝載時將被讀取(請注意並不影響class的執行,由於Annotation與class在使用上是被分離的)。使用這個meta-Annotation能夠對 Annotation的「生命週期」限制。
做用:表示須要在什麼級別保存該註釋信息,用於描述註解的生命週期(即:被描述的註解在什麼範圍內有效)
取值(RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在運行時有效(即運行時保留)
@Documented:
@Documented用於描述其它類型的annotation應該被做爲被標註的程序成員的公共API,所以能夠被例如javadoc此類的工具文檔化。Documented是一個標記註解,沒有成員。
@Inherited:
@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的類型是被繼承的。若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。
注意:@Inherited annotation類型是被標註過的class的子類所繼承。類並不從它所實現的接口繼承annotation,方法並不從它所重載的方法繼承annotation。
當@Inherited annotation類型標註的annotation的Retention是RetentionPolicy.RUNTIME,則反射API加強了這種繼承性。若是咱們使用java.lang.reflect去查詢一個@Inherited annotation類型的annotation時,反射代碼檢查將展開工做:檢查class和其父類,直到發現指定的annotation類型被發現,或者到達類繼承結構的頂層。
編寫代碼:
註解類:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface UserName { String name() default ""; }
JavaBean:
package com.demo.model; import Annotation.UserName; import org.springframework.stereotype.Component; import javax.persistence.*; import java.io.Serializable; import java.util.Date; /*@Entity @Table(name = "user")*/ @Component public class User implements Serializable { /* @Id @GeneratedValue(strategy = GenerationType.AUTO)*/ private int userId; private int userCode; private int userNmber; @UserName(name="梨花") private String userName; private int userPhone; private String userIdCard; @Temporal(TemporalType.TIMESTAMP) private Date regDate; private String regCannal; private String regPic1; private String regPic2; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public int getUserCode() { return userCode; } public void setUserCode(int userCode) { this.userCode = userCode; } public int getUserNmber() { return userNmber; } public void setUserNmber(int userNmber) { this.userNmber = userNmber; } public String getUserName() { return userName; } @UserName(name="梨花") public void setUserName(String userName) { this.userName = userName; } public int getUserPhone() { return userPhone; } public void setUserPhone(int userPhone) { this.userPhone = userPhone; } public String getUserIdCard() { return userIdCard; } public void setUserIdCard(String userIdCard) { this.userIdCard = userIdCard; } public Date getRegDate() { return regDate; } public void setRegDate(Date regDate) { this.regDate = regDate; } public String getRegCannal() { return regCannal; } public void setRegCannal(String regCannal) { this.regCannal = regCannal; } public String getRegPic1() { return regPic1; } public void setRegPic1(String regPic1) { this.regPic1 = regPic1; } public String getRegPic2() { return regPic2; } public void setRegPic2(String regPic2) { this.regPic2 = regPic2; } @Override public String toString() { return "User{" + "userId=" + userId + ", userCode=" + userCode + ", userNmber=" + userNmber + ", userName='" + userName + '\'' + ", userPhone=" + userPhone + ", userIdCard='" + userIdCard + '\'' + ", regDate=" + regDate + ", regCannal='" + regCannal + '\'' + ", regPic1='" + regPic1 + '\'' + ", regPic2='" + regPic2 + '\'' + '}'; } }
註解解析類:
public class ParseAnnotion<T> { /** * 解析註解UserName * * @param annoClass*/ public T parseUserName(Class<T> annoClass){ Class<T> cls= annoClass; try { Object o=cls.newInstance(); if(cls!=null){ Field[] fields=cls.getDeclaredFields(); //寫 for(Field field:fields){ UserName userName=field.getAnnotation(UserName.class); if(userName!=null){ PropertyDescriptor descriptor=new PropertyDescriptor(field.getName(),cls); Method method=descriptor.getWriteMethod(); method.invoke(o,userName.name()); } } return (T) o; } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IntrospectionException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } }
main方法:
ParseAnnotion<User> userParseAnnotion=new ParseAnnotion<User>(); User user=userParseAnnotion.parseUserName(User.class); System.out.println(user.getUserName());
這個註解的功能簡單的實現了獲取屬性的註解上的值的功能。