java 封装优化工具_利用Java注解的简单封装的一次优化

悟红尘:​zhuanlan.zhihu.comzhihu-card-default.svg

在我们的项目中和后台的通信的时候,为了防止别人截获并篡改信息,于是决定启用一套自己验签规则,那就是将所有属性的值拼接起来进行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 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值