一. 元注解
自定义注解首先需要了解四个元注解
,它是注解在注解上的注解,用于定义自定义注解的特性。
- @Retention
用于表示注解在什么情况下生效。
RetentionPolicy.SOURCE(编译器不会将注解编译到class中)
RetentionPolicy.CLASS(会编译到class但不会被加载到jvm)
RetentionPolicy.Runtime(在jvm中生效) - @Documented
注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。 - @Target
作用的位置,是作用于class还是field等。
取值为 ElementType枚举类。 - @Inherited
该注解作用的class或field等可以被子类继承。
值得一提,定义注解是 public @interface Demozhujie{} 的方式来定义的,@interface不能够implements和extends。
下面是一个demo,演示如何定义一个注解。
import java.lang.annotation.*;
@Inherited
@Documented
@Target({ElementType.Field})
@Retention(RetentionPolicy.RUNTIME)
public @interface Translate {
/**
@interface定义字段的方式与一般的class不同,需要()。
*/
String value();
boolean enable() default true;
}
二. 如何处理注解
了解定义注解,使用注解其实不用多说,放在想要加的位置即可。
那么我们又该如何使用注解呢?常用的方式是通过spring aop或其他aop方式在某个位置拦截进行注解的逻辑处理,我们的重点不是aop,所以下面只是一个拦截到注解时的代码逻辑。
示例:@Translate注解表示的字段全部翻译为英文,当然这里的英文。
// 1. 通过反射获取到注解,clz是当前class
Class clz = ...
Translate annotation = (Translate) clz.getAnnotation(Translate.class);
// 2. 判断当前class哪个字段被加了注释
Arrays.stream( clz.getFields() )
.forEach( field -> {
if(field.isAnnotationPresent(Translational.class) && field.getAnnotation(Translational.class).enable()){
markFields.add(field.getAnnotation(Translational.class).value());
}
});
//3. 根据第二步找到的字段,通过反射调用getter方法获取到属性值
// element为当前正处理的对象
// getIdMethodName需要驼峰,这里就不做字母的大小写转换了
String getIdMethodName = "get"+markFields.get(0);
Object fieldValue = MethodUtils.invokeMethod(element,getIdMethodName);
//4. 将上一步获取到的属性值与字典数据对比,通过反射调用setter方法替换属性值
String translateValue = getValueByDICT(fieldValue);
MethodUtils.invokeMethod(element,setIdMethodName,translateValue);