自定义注解使用
我們怎么去定義一個自己的一個注解,我們怎么定義呢,這就跟你講一下,我們講一下我們自己手寫一個注解,實現類似于Spring里的注解功能,那這個我們怎么辦呢,自定義注解比較簡單,你們之前可能也都用過了,在這里我就做一個自定義注解,去獲取到注解上的一些信息,給大家演示一下,定義注解的話誰有印象,有沒有人之前搞過的,你們下去有興趣的可以看一下,他的源碼里面寫了,你們可以看一下,@Transactional,他源碼里面是不是也是這樣寫的,專門定義一個包寫注解的,具體實現我們待會再說,接著我們來寫一下,定義一下這個注解
package com.learn.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 我們定義一個注解* 我們通過@interface這個關鍵字* 可以去定義注解了* 那這就是我們的注解了* 看到沒有* 那我們怎么去用這個注解* 給你們說一下* 我們這樣用* 我們去看一下* 這里我們定義了一個add注解* 通過@interface這個關鍵字定義起來* 我可以把注解加上去的* 這個注解有幾個特性說一下* 你可以設置這個注解在哪些權限上用到* @Target里面就可以去引用一下* 表示這個注解可以在哪些地方用到* 他的約束* 他只能在METHOD* 在方法上進行使用* 那么這個時候我給你講一下* 這個時候你會發現你的注解只能在方法上定義了* 不能夠在類上進行定義了* 你可以看一下里面的類型ElementType* 他還有很多類型* 這個作用干嘛用的呢* 記住@Target這個注解作用是干嘛用* 設置你注解的權限* 還少一個* 咱們再加一個權限* 你們也可以寫成數組形式* ElementType.Type* 這個時候你就不能在方法上進行使用了* 你們可以看一下* 只能在類上進行使用了* 在這里有很多權限* 具體怎么約束呢* 你們下去看看有很多參數* 就是Target里面有很多參數* 我就不去講了* 因為這個都比較簡單* 你們自己下去看一下文檔* 去實驗就行了* 這里面還有一個標識* 就是@Retention這個注解* 目的是干嘛用的呢* 你們在上面還要講一個注解* 加@Retention這樣的一個注解* 表示整個描述的一個生命周期* 我們在運行的時候可以用到這樣的一個注解的* 那么怎么用呢* 用的話也是比較容易的* RetentionPolicy.RUNTIME* 你用到這樣的時候* 項目運行的時候* 你就可以用到注解里面的功能了* 然后給你們講一下* 我們不是要手寫Spring的事務注解嗎* 記住啊* 這段代碼一定要加* 反射想要獲得注解的情況下* 這段代碼是必須要加的* 要不然以為他反射沒有用到這個注解* 項目運行的時候* 就相當于運行的時候調用這個注解的* 所以這個注解最好是設置一下* 那么這個定義好了之后* ElementType.METHOD* 我們讓他在方法上進行使用* * * @author Leon.Sun**/
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
// @interface 定義注解
public @interface AddAnnotation {// 手寫Spring事務注解/*** 我們在這里寫一個方法* int類型的userId()* 默認值多少呢* 默認為0* 是不是這樣的* * * @return*/int userId() default 0;/*** 我們還可以繼續寫* String類型的userName()* 然后我們default默認名稱* * * @return*/String userName() default "默認名稱";/*** 我們再寫一個定義數組* 你們也可以給一個初始化* 這個看你們自己* 寫一個方法* 整個就寫完了* 這里我們定義三個方法之后* * * @return*/String[]arrays();
}
package com.learn.annotation;import java.lang.reflect.Method;/*** 在類上定義就直接報錯了* 看到效果沒有* * * @author Leon.Sun**/
//@AddAnnotation
public class User {/*** 你們看一下@AddAnnotation這個注解是直接可以用的* 看到沒有* 這個比較簡單* 這里加了幾個參數* userName我們就叫做張三* 然后再寫userId等于18* 我們就可以設置18歲* 我們再來一個參數叫做數組arrays* 我就可以寫一個值* 叫做1* 那么這個寫完了之后* 這個定義注解難不難* 不難吧應該* 這個都是屬于JAVASE的知識* 不是很難* 那么這個寫完了之后* 我就給你們講一下* 通過反射機制獲取注解參數* 這都是固定格式* 只要定義多了就OK了* * */@AddAnnotation(userName = "張三", userId = 18, arrays = { "1" })public void add() {}public void del() {}public static void main(String[] args) throws ClassNotFoundException {// 怎么樣獲取到方法上注解信息 反射機制Class<?> forName = Class.forName("com.learn.annotation.User");// 獲取到當前類(不包含繼承)所有的方法Method[] declaredMethods = forName.getDeclaredMethods();for (Method method : declaredMethods) {// 獲取該方法上是否存在注解System.out.println("####方法名稱" + method.getName());AddAnnotation addAnnotation = method.getDeclaredAnnotation(AddAnnotation.class);if (addAnnotation == null) {// 該方法上沒有注解System.out.println("該方法上沒有加注解..");continue;}// 在該方法上查找到該注解System.out.println("userId:" + addAnnotation.userId());System.out.println("userName:" + addAnnotation.userName());System.out.println("arrays:" + addAnnotation.arrays());System.out.println();}}}
實現自定義注解
元注解的作用就是負責注解其他注解。Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它
annotation類型作說明。Java5.0定義的元注解:
@Target
@Target說明了Annotation所修飾的對象范圍:Annotation可被用于 packages、types(類、接口、枚舉、Annotation類型)、
類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數)。在Annotation類型的
聲明中使用了target可更加明晰其修飾的目標。
1. CONSTRUCTOR:用于描述構造器
2. FIELD:用于描述域
3. LOCAL_VARIABLE:用于描述局部變量
4. METHOD:用于描述方法
5. PACKAGE:用于描述包
6. PARAMETER:用于描述參數
7. TYPE:用于描述類、接口(包括注解類型) 或enum聲明2.@Retention
表示需要在什么級別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內有效)
3.@Documented
4.@Inherited
?
總結
- 上一篇: JDK注解概述
- 下一篇: 手写自定义注解实现思路