1. 程式人生 > >Java 註解入門例項 && 註解傳參

Java 註解入門例項 && 註解傳參

概念:java提供了一種原程式中的元素關聯任何資訊和任何元資料的途徑和方法 
JDK內建系統註解: 
@Override 用於修飾此方法覆蓋了父類的方法; 
@Deprecated 用於修飾已經過時的方法; 
@Suppvisewarnings 用於通知java編譯器禁止特定的編譯警告。 
常見註解 
註解按照執行機制劃分 
原始碼註解:註解只在原始碼中存在,編譯成.class檔案就不存在了; 
編譯時註解:註解在原始碼和.class檔案中都存在(例:JDK自帶註解); 
執行時註解:在執行階段還起作用,甚至會影響執行邏輯的註解(Autowired); 
自定義註解的元註解

  1. @Target—作用域(constructor(構造方法宣告),field(欄位宣告),local_variable(區域性變數宣告),method(方法宣告),package(包宣告),parameter(引數宣告),type(類,介面宣告))
  2. @Retention—生命週期(source:只在原始碼顯示,編譯時會丟棄。class:編譯時會記錄到class中,執行時忽略。runtime:執行時存在,可以通過反射讀取)
  3. Inherited—標識註解(允許子類繼承)
  4. Documented—生成Javadoc
  5. 若成員只有一個,必須為value,這個引數賦值可以不寫value=XXX

自定義語法 
使用自定義 
成員以無參無異常方式宣告。成員型別是受限的,合法的型別包括原始型別及String,Class,Annotation, Enumeration.

上面用了註解,程式中獲得註解資訊的方法是反射。 
Class cls = Class.forName(“”);//使用類載入器載入類 
cls.isAnnotationPresent(xx.class);//判斷cls這個類上是否有xx的註解,找到類上註解 
xx a = (xx)cls.getAnnotation(xx.class);//取得其上的註解

下面附一個例項,是框架如何使用註解描述引數。 
結構圖 
這裡寫圖片描述

A.java

package javaBasic;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER ,ElementType.METHOD
}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface A { String value(); String name() default "bingone"; int age() default 20; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

B.java

package javaBasic;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER ,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface B {
    String value();
    String name() default "bingone";

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

DataClass.java

package javaBasic;

public class DataClass {
    public String name;
    public int age;
    public DataClass(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

RunClass.java

package javaBasic;

public class RunClass {
    public static void run(@A("str") String str,@B("age")int age){
        System.out.println("In run Method str:" + str + "age:" + age);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

TestClass.java

package javaBasic;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
/**
 * 通過註解傳引數
 * @author gg_gogoing
 *
 */
public class TestClass {
    public static void parseMethod(DataClass data,Object obj,String mthname){
        //驗證是否有註解
        //若有則兩種方法:
        //1. 在編譯時刻已經有了對應的表,查表即可
        //2. 如下的遍歷方式。
        if(obj instanceof RunClass){
            String str = null;
            int age = 0;
            Method [] methods = (Method[])obj.getClass().getMethods();
            for(Method method :methods){
                if(method.getName().equals(mthname)){
                    Annotation[][] annotations = method.getParameterAnnotations();
                    for(Annotation[] tt : annotations){
                        for(Annotation t:tt){
                            if(t instanceof A){
                                str = data.name;
                            }else if(t instanceof B){
                                age = data.age;
                            }
                        }
                    }
                    RunClass.run(str, age);
                }
            }
        }
    }

    public static void main(String[] args) throws Exception, RuntimeException { // 主方法
        //不直接傳引數,而是將一個類中的資料傳入
        DataClass dc = new DataClass("gg_gogoing", 20);
        parseMethod(dc, new RunClass(), "run");

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

附一張大圖

========================================================

日誌記錄簡化,只需要在action或者controller的方法上加logging註解即可。註解:@Logging(description = "{username}登入"),description是註解內容,{}中為動態引數,是傳入該方法中的指定po的屬性。

註解類程式碼:

  1. package cn.com.annotation;  
  2. import java.lang.annotation.Documented;  
  3. import java.lang.annotation.ElementType;  
  4. import java.lang.annotation.Retention;  
  5. import java.lang.annotation.RetentionPolicy;  
  6. import java.lang.annotation.Target;  
  7. /** 
  8.  * 日誌註解 
  9.  * @author ZhangShaobo 
  10.  * @date 2017-09-04 
  11.  */
  12. @Documented
  13. @Retention(RetentionPolicy.RUNTIME)  
  14. @Target(ElementType.METHOD)  
  15. public@interface Logging {  
  16.     String description();  
  17. }  

具體的日誌實現類,該類中loginfo方法需要在攔截器中呼叫。
  1. package cn.com.util;  
  2. import java.lang.reflect.Method;  
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6. import java.util.regex.Matcher;  
  7. import java.util.regex.Pattern;  
  8. import org.apache.poi.ss.formula.functions.T;  
  9. import org.slf4j.Logger;  
  10. import org.slf4j.LoggerFactory;  
  11. import cn.com.annotation.Logging;  
  12. /** 
  13.  * 日誌註解的具體實現類 
  14.  * @author ZhangShaobo 
  15.  * @date 2018-09-04 
  16.  */
  17. publicclass LogAnnoUtil {  
  18.     privatestatic Logger log = LoggerFactory.getLogger(LogAnnoUtil.class);  
  19.     /** 
  20.      * 根據註解記錄日誌 
  21.      * @param t action物件 
  22.      * @param methodName 呼叫的action方法名稱 
  23.      * @param map 引數map 
  24.      */
  25.     publicstatic <T> void loginfo(T t, String methodName, Map map){  
  26.         Method [] methods = t.getClass().getDeclaredMethods();  
  27.         for (final Method m : methods) {  
  28.             if (m.getName().equals(methodName)) {  
  29.                 if(m.isAnnotationPresent(Logging.class)){  
  30.                     String desc = m.getAnnotation(Logging.class).description();  
  31.                     List<String> list = descFormat(desc);  
  32.                     for (String s : list) {  
  33.                         String value = map.get(s).toString();  
  34.                         desc = desc.replace("{"+s+"}", value);  
  35.                     }  
  36.                     // 暫時只是輸出到了控制檯,具體需要存庫或者存快取,需要改這段程式碼
  37.                     log.info(desc);  
  38.                 }  
  39.             }  
  40.         }  
  41.     }  
  42.     /** 
  43.      * 獲取日誌資訊中的動態引數,然後替換 
  44.      * @param desc 
  45.      * @return 
  46.      */
  47.     privatestatic List<String> descFormat(String desc){  
  48.         List<String> list = new ArrayList<>();  
  49.         Pattern pattern = Pattern.compile("\\{([^\\}]+)\\}");   
  50.         Matcher matcher = pattern.matcher(desc);   
  51.         while(matcher.find()){   
  52.             String t = matcher.group(1);   
  53.             list.add(t);  
  54.         }  
  55.         return list;  
  56.     }  
  57. }  

攔截器中寫呼叫,以上程式碼實現的是在struts框架中用註解記錄日誌,springmvc或者springboot需要適當更改程式碼。有好的建議或者有不明白的地方歡迎評論溝通!

相關推薦

Java 註解入門例項 && 註解

概念:java提供了一種原程式中的元素關聯任何資訊和任何元資料的途徑和方法 JDK內建系統註解: @Override 用於修飾此方法覆蓋了父類的方法; @Deprecated 用於修飾已經過時的方法; @Suppvisewarnings 用於通知java編譯器禁止特定的編譯警

Mybatis入門例項(註解實現)(3)

這裡做一個補充實現,前面我們是使用的基於配置檔案XML實現的,但是Mybatis其實還提供了另一種實現方式,那就是使用註解實現,所以我在這裡補充一下註解的實現。 1. 程式碼結構 從程式碼結構看我們只是增加了UserDaoAnnotation.j

Java 010 面向物件(、鏈式程式設計、包、修飾符、內部類)

知識點梳理 心得體會 小知識點 1.只要返回的是物件就可以用==.調方法,來鏈式程式設計== 2.手動導包時,一定要寫到包的最終目錄,有時候用==*代替是會報錯的 3.protected受保護許可權;只能在子類裡面==呼叫父類受保護成員 4.區域性內部類訪問的外部類資料必須

java POST請求兩種方式JSON格式和表單格式

JSON格式: JSONObject jsonObject = new JSONObject();         jsonObject.put("Action", "action");        &n

JAVA NIO入門例項

基本概念:參考http://zhangshixi.iteye.com/blog/679959作者的系列文章即可 NIO因為其高效性,成為了服務端的首選,大大提高了服務端的響應效率。 我自己讀完作者的文章,寫了一個簡單的DEMO 服務端: package com.liuc.i

java基於HTTP協議post,獲取引數

post傳參和獲取引數: /** * 獲取post引數 * @param is * @param charset * @return */ public static String getContent(InputStream is, St

Java爬蟲入門例項

想copy個爬蟲玩玩,結果提到用的jar包是apache的http客戶端開源專案---HttpClient 就下載了一個版本4.3 HttpClient httpclient = new Ht

java 之方法呼叫 方法 值傳遞還是引用傳遞位元組碼

/*Java中的引數傳遞方式到底是引用傳遞還是值傳遞?java核心技術卷I裡有一個結 論我覺得挺有意思的:java中沒有引用傳遞,只有值傳遞 首先看定義: 值傳遞,是指方法接收的是呼叫者提供的值 引用傳遞,是指方法接收的是呼叫者提供的變數地址 事實上,Java中方法引

Java入門到放棄》入門篇:使用註解的方式配置hibernate映射關系

如果 borde 版本 tar -s 相關 generate rate p s 之前我們都是使用配置文件的方式來生成的代碼,雖然和JDBC比較簡單了很多,但每次都在修改時需要既改實體類又改映射文件。還是有點麻煩。 所以,這一篇,我們來說說使用註解的方式來在接在實體類上配置映

JAVA - Annotation 註解 入門

其它 基本類 target warnings 提示 並且 有效 註釋 ride Java註解提供了關於代碼的一些信息,但並不直接作用於它所註解的代碼內容。在這個教程當中,我們將學習Java的註解,如何定制註解,註解的使用以及如何通過反射解析註解。 Java1.5引入了註

mybatis使用@param("xxx")註解和不使用的區別

color class myba rdo rec delete ger con inter public interface SystemParameterMapper { int deleteByPrimaryKey(Integer id); int

mybatis 詳解(三)------入門例項(基於註解

目錄 1、建立MySQL資料庫:mybatisDemo和表:user 2、建立一個Java工程,並匯入相應的jar包,具體目錄如下 3、在 MyBatisTest 工程中新增資料庫配置檔案 mybatis-configuration.xml 4、定義表所對應的實體

Swagger註解

[@Api] @ Api用於宣告Swagger資源API。 它有雙重用途 - 它會 影響資源列表_和_ API宣告。 只有使用@ Api註釋的類才會被Swagger掃描。 在資源清單中,註釋將轉換為[資源物件] 在API宣告中,它基本上將作為[API宣告]本身的基礎。

使用Java、hibernate validator註解校驗入,格式化出(入

在專案執行真正業務程式碼前,一般都需要對於前端的入參值進行一輪的判斷,而一般的做法是寫if語句進行值的判斷,如下例子 public boolean insertOneUser(String name, int age) { if (name == null || n

java 自定義註解應用例項

本例子旨在使用自定義註解為實體打上標記,為自動生成 sql 提供依據,模擬 hibernate 的註解,至於註解的原理自己搜吧1.定義 Table 註解package test; import java.lang.annotation.Documented; import

java/SpringBoot http post請求json資料格式(有詳細註解

java http post請求傳json資料格式,試了很多的方式,用了下面這個是可以 import net.sf.json.JSONObject; 2 import org.apache.commons.httpclient.*; 3 import

struts2使用註解配置Action方式

@Action(value = "operatorRoleAction", results = { @Result(name = "view", location = "/bussiness/operatorrole_view.jsp", type = "dispatche

深入理解Java註解(Annotation)自定義註解入門

要深入學習註解,我們就必須能定義自己的註解,並使用註解,在定義自己的註解之前,我們就必須要了解Java為我們提供的元註解和相關定義註解的語法。 元註解:   元註解的作用就是負責註解其他註解。Java5.0定義了4個標準的meta-annotation型別,它們被用來

Java中常見的註解

ise rri 自帶 com doc ret not article 標識 Java中常見的註解 [email protected]/* */ @Deprecated @Suppvisewarnings 常見第三方註解 Spring:@Autowired

java

his rgs clas text package println 成員 .get 方法 package 練習; public class nini { //姓名 private String name; //年齡 private int age; //構造方法 publi