利用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的英文意思是可重复的。顾名思义说明被这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。

好了,那下面我们说说我们最上面说的签名的优化,首先定义注解:

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;
}

接着利用反射,根据顺序拼接字符串:

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();
}

好了 我们测试下,先定义个bean:

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;
    }
}
public static void main(String[] args) {
    Student student = new Student();
    student.setAge(100);
    student.setName("小明");
    student.setSex("男");
    student.setAddress("上海");
    System.out.println(getValue(student));
}

结果是: 上海男小明

因为地址的sort为0,sex的sort为1,那么的sort为2
OK 完成
欢迎关注我的公众号:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟红尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值