自定义注解
Java 中自定义注解和创建一个接口相似, 自定义注解的格式是以 @interface 为标志的.
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE})
- public @interface SPI {
- /**
- * default extension name
- */
- String value() default "";
- }
我们知道 java.lang.annotation 包中有一个 Annotation 的接口, 它是所有注解类型扩展的公共接口. 那我们是否可以直接通过实现该接口来实现自定义注解呢?
- import java.lang.annotation.Annotation;
- public class MyAnnotation implements Annotation {
- @Override
- public Class<? extends Annotation> annotationType() {
- return null;
- }
- }
发现 Annotation 接口中只有一个 annotationType 的方法, 而且通过 Annotation 源码的注释我们可以发现答案是不能.
汉译即为: Annotaion 被所有注解类型继承, 但是要注意: 手动扩展继承此接口的接口不会定义注解类型. 另请注意, 此接口本身不定义注解类型.
使用场景
自定义注解的使用场景很多, 我们在造轮子写框架的过程经常会使用到, 例如我最近就遇到了一个业务场景: 像一些编辑业务信息的接口, 产品要求信息编辑后的新旧值对比, 对比的业务功能, 我们的实现方式是拿到前端填写的 Form 表单 (新值) 和数据库中查询出来的 Dto(旧值)通过反射技术获取到相同属性字段名, 再比较属性值就可以得出新旧值. 得到值之后我们也知道该字段的 Dto 中的字段名, 但是如何将比较得到的新旧值字段的中文名返回给前端呢? 例如:
- public class Stedent {
- private String name;
- private int age;
- private String sex;
- // 省略 setter,getter
- }
比较后我们的结果是 name : "xiaoming"-> "daming",age : 24 -> 26. 但是我们不能直接将 name 和 age 返回给前端, 他们需要的格式是: 姓名: "xiaoming"-> "daming", 年龄 : 24 -> 26. 这时候就可以考虑自定义一个注解 @FieldName,
- @Deprecated
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface FieldName {
- String value() default "";
- }
然后将该注解加在属性字段上面
- public class Student {
- @FieldName(value = "姓名")
- private String name;
- @FieldName(value = "年龄")
- private int age;
- @FieldName(value = "性别")
- private String sex;
- // 省略 setter,getter
- }
之后就可以通过反射获取该字段中文名.
- // 如果 oldField 属性值与 newField 属性值的内容不相同
- if (!isEmpty(newValue)) {
- Map<String, Object> map = new HashMap<>();
- String newFieldName = newField.getName();
- if (newField.isAnnotationPresent(ApiModelProperty.class)) {
- ApiModelProperty apiModelPropertyAnno = newField.getAnnotation(ApiModelProperty.class);
- newFieldName = apiModelPropertyAnno.value();
- else if (newField.isAnnotationPresent(FieldName.class)) {
- FieldName fieldNameAnno = newField.getAnnotation(FieldName.class);
- newFieldName = fieldNameAnno.name();
- }
- map.put(FIELD_NAME, newFieldName);
- map.put(OLD_VALUE, oldValue);
- map.put(NEW_VALUE, newValue);
- list.add(map);
- }
来源: https://www.cnblogs.com/jajian/p/9576466.html