利用Java註解的簡單封裝,進行的一次優化

在我們的項目中和後臺的通信的時候,為了防止別人截獲並篡改信息,於是決定啟用一套自己驗籤規則,那就是將所有屬性的值拼接起來進行SHA256簽名,在這個字符串拼接的時候如果屬性少還好,直接寫一個方法將屬性值拼接起來就好了,但是如果屬性很多的話,並且需要多次不同的數據與後臺進行交互,每次寫個方法拼接太麻煩了,為了造福後來者,使拼接變得簡單,所以用註解進行了優化。

註解是的作用是在類或者方法,屬性等上面打上一個標籤,然後通過java的反射機制動態的對打上標籤的內容進行解析和處理。

在Java中已經內置了幾個註解,我們平常可能有看到:

@Override 用在方法上,表示要覆蓋父類中的方法

@Deprecated 表示被棄用的代碼,如果使用了被他標註的方法會提示警告

@SuppressWarnings,關閉不當編譯器警告信息。

我們可以使用元註解自定義自己的註解,首先需要明白什麼是元註解,元註解是java中用於表示註解的註解,java中元註解分為:@Retention、 @Target、 @Document、 @Inherited和@Repeatable

@Retention

標示的是註解存留的階段,有一個枚舉類:RetentionPolicy.SOURCE 僅存於源碼中RetentionPolicy.CLASS 存在於字節碼中,但是在運行時無法獲得RetentionPolicy.RUNTIME 在運行是可以通過反射獲得,前面也說過註解的目的是通過反射機制動態的獲取值,那麼我們最常用的那肯定就是這個了

@Target

目標的意思,是說我們制定的註解是用於什麼地方,比如方法,屬性,還是類等,同樣有一個枚舉:ElementType.TYPE 表示可以作用於類,方法,枚舉 ElementType.FIELD 作用於屬性 ElementType.METHOD 作用於方法。。。還有其他的就不說了,反正也不常用,用的時候再看吧

@Documented

它的意思是文檔,作用是能將註解包含的Javadoc中去,其實要是用工具javadoc生成文檔的時候用,不需要搞什麼文檔的話,加不加沒啥區別

@Inherited

繼承的意思,就是子類如果沒有其他別的註解的話,可以繼承父類標註的註解

@Repeatable

Repeatable的英文意思是可重複的。顧名思義說明被這個元註解修飾的註解可以同時作用一個對象多次,但是每次作用註解又可以代表不同的含義。

好了,那下面我們說說我們最上面說的簽名的優化,首先定義註解:

<code>import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface ValidateValue {    //是否參與驗證    boolean isValidate() default false;    //排序值    int sortValue() default 0;}/<code>

接著利用反射,根據順序拼接字符串:

<code>public static String getValue(Object object){    Class aClass = object.getClass();    //獲取所有聲明的屬性    Field[] declaredFields = aClass.getDeclaredFields();    //過濾出所有帶有註解的屬性    List<field> fields = new ArrayList<>();    for (Field field : declaredFields){        if(field.isAnnotationPresent(ValidateValue.class)){            ValidateValue annotation = field.getAnnotation(ValidateValue.class);            if(annotation.isValidate()){                fields.add(field);            }        }    }    //根據定義的順序排序    Collections.sort(fields, (o1, o2) -> {        ValidateValue annotation1 = o1.getAnnotation(ValidateValue.class);        ValidateValue annotation2 = o2.getAnnotation(ValidateValue.class);        return annotation1.sortValue() - annotation2.sortValue();    });    StringBuilder sb = new StringBuilder();    for (Field field : fields){        field.setAccessible(true);        try {            //獲取屬性的值,因為都是基本類型,並且拼的是字符串,所以不用判斷獲得值是什麼類型,直接用object即可            Object value = field.get(object);            sb.append(value);        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }    return sb.toString();}/<field>/<code>

好了 我們測試下,先定義個bean:

<code>public class Student {    @ValidateValue(isValidate = true, sortValue = 0)    private String address;    @ValidateValue(isValidate = true, sortValue = 2)    private String name;    @ValidateValue(isValidate = true, sortValue = 1)    private String sex;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getSex() {        return sex;    }    public void setSex(String sex) {        this.sex = sex;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }}/<code>
<code>public static void main(String[] args) {    Student student = new Student();    student.setAge(100);    student.setName("小明");    student.setSex("男");    student.setAddress("上海");    System.out.println(getValue(student));}/<code>

結果是: 上海男小明

因為地址的sort為0,sex的sort為1,那麼的sort為2

OK 完成


利用Java註解的簡單封裝,進行的一次優化


分享到:


相關文章: