一.什么是注解
annotation是注解的意思 ,注解可以理解为标记,用来标记一些辅助信息。
其实呢,Java中有一类接口 本身不用被实现,只是作为一个标记用的存在。
标记的目的显然是为了进行 区别,识别,分类,这样做的目的 就明显了,分类之后可以制定统一的规则来进行处理。处理的依据就是注解里面含有的信息.
那么注解本身就是一个标记,可以用于分类,从而使用注解可以 获取一个 类的集合或者是一个方法的集合..
从而为我们下一步的处理提供一个输入集合,可以让我们以一个高度统一的动作来处理一些 同一个标记的 对象
领悟其中的精髓: 标记,分类,储存辅助信息.
有了这个标记,我们可以使用反射来分析类,然后进行归类,(aop 的切点不也是为了进行归类吗),
辅助的信息其实就是可以放到配置文件中的那些配置信息,这些东西的灵活配置增加了灵活度,因此注解里面可以放置一些固定的信息
有了这些 作用,那么就可以依据注解里面的配置信息 对注解修饰的 东西 (类,对象,字段,方法) 进行一些处理。
比如 : 校验 ,我们可以在VO的字段上加上注解来存储校验的规则信息,当然这些规则只是固定的验证规则而已
导入/导出 ,可以在vo中的字段加上该字段将是excel中的第几列,有什么格式化的规则等等
aop:使用特定的主键可以作为一个拦截标志,然后配合注解中的固定信息给出拦截器处理的动作功能,
如计算方法的执行时间,方法的输入参数打印,事务管理等
二.使用方法
2.1 定义
2.2注解的使用范围
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface FieldInfo {
String value() default "";
}
2.2.1 @Retention:修饰注解的有效期
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
用@Retention(RetentionPolicy.SOURCE )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中
用@Retention(RetentionPolicy.RUNTIME )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时, 会被虚拟机保留在运行时
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE
}
2.3 注解接口内部的成员
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldInfo {
/**
* 字段名称
*/
String name() default "";
/**
* 标记一个字段是否是必填项目
*/
boolean required() default false;
/**
* 依赖于其他项目字段条件必填
*/
boolean dependsRequired() default false;
/**
* dependsRequired为true的时候,标记一个字段条件必填的依赖字段
*/
String[] dependsField() default {};
/**
* dependsRequired为true的时候,条件必填时候的策略
*/
CheckStrategyEnum checkStrategy() default CheckStrategyEnum.NULL;
/**
* 是否进行长度校验
*/
boolean lengthCheck() default false;
/**
* 默认字段值长度
*/
int length() default 0;
}
@FieldInfo(name = "打款账户名中文名", required = false, dependsRequired = true, dependsField = {"currency"}, checkStrategy = CheckStrategyEnum.PRODUCT_CURRENCY_RMB)
private String bankAccountName = null;
2.4 注解和类的继承或接口的实现
2.4.1 接口的实现
如果注解修饰了接口中的方法,那么实现类中的方法是获取不到该注解信息的
2.4.2 父类和子类
同上面一样。
但是呢修饰在类上面的注解如果子类想获取到信息的话可以使用 @Inherited 修饰该注解
2.5 注解信息的获取
FieldInfo fdInfoAnno = null;
Field f = claz.getXXXXX ;
if (f.isAnnotationPresent(FieldInfo.class)) {
fdInfoAnno = f.getAnnotation(FieldInfo.class);
chName = fdInfoAnno.name();
boolean required = fdInfoAnno.required();
...
}
class和method上面注解的获取是一样的。
如果注解是修饰在接口中的方法,实现类的如何获取呢?
Class<?>[] interfaces = bean.getClass().getInterfaces();
获取到接口的类,然后将这些类再按照上面的获取方法 可以得到