java元注解详解
要想灵活应用自定义注解,首先来深入了解一下java元注解
@Inherited
- 类继承关系中,子类会继承父类中带有@Inherited的注解;
- 接口继承关系中, 子接口不会继承父类接口的任何注解,不管有没有被@Inherited修饰
- 类实现关系中,实现类不会继承任何接口的注解
- @Target
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型),类型成员(方法、构造方法、成员变量、枚举值),方法参数和本地变量(如循环变量,catch参数),在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
作用:用户描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(ElementType)有:
类型 | 用途 |
---|---|
CONSTUCTOR | 用于描述构造器 |
FIELD | 用于描述域 |
LOCAL_VARIABLE | 用于描述局部变量 |
METHOD | 用于描述方法 |
PACKAGE | 用于描述包 |
TYPE | 用于描述类,接口(包括注解类型)或enum声明 |
使用实例:
@Target(ElementType.TYPE)
public @interface Table {
/** * 数据表名称注解,默认值为类名称 * @return */
public String tableName() default "className";
}
@Target(ElementType.FIELD)
public @interface NoDBColumn {
}
注解Table可以用于注解类、接口(包括注解类型)或者enum声明,而注解NoDBColumn仅可用于注解类的成员变量
- @Retention
该被保留的时间长短:某些Annotion仅出现在源码中,儿被编译器丢弃;而另一些被编译在class文件中;编译在class中的Annotion可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotion与class在使用上是被分离的)。使用这个meta-Annotation可以对Annotion的“生命周期” 限制。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:别描述的注解在什么范围有效)
取值(RetentionPoicy)有:
类型 | 作用 | 说明 |
---|---|---|
SOURCE | 在源文件中有效(即源文件保留) | 仅出现在源代码中,而被编译器丢弃 |
CLASS | 在class中有效(即在class保留) | 被编译在class文件中 |
RUNTIME | 在运行时有效(即运行时保留) | 编译在class文件中 |
Retention meta-annotion类型有唯一的value作为成员,他的取值来自java.lang.annotionPolicy的枚举类型。具体实例如下;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String name() default "fieldName";
public String setFuncName() default "setField";
public String getFuncName() default "getField";
public boolean defaultDBValue() default false;
}
Column注解的RetentionPolicy的属性值是RUNTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理
- @Documented
该注解用于描述其他类型的annotion应该被作为被标注的程序成员的公共API,因为可以被例如,javadoc此类的工具文档化,Documented是一个标记注解,没有成员。 - @Native since 1.8
@Repeatable since 1.8
此注解为了解决注解不能再同一个地方重复使用而出现的。可以查看spring 定时任务注解@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {String CRON_DISABLED = "-";
String cron() default "";
String zone() default "";
long fixedDelay() default -1L;
String fixedDelayString() default "";
long fixedRate() default -1L;
String fixedRateString() default "";
long initialDelay() default -1L;
String initialDelayString() default "";
}
然后还需定义容器注解@Schedules,这样@Scheduled多个才可以正常使用
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Schedules {
Scheduled[] value();
}
还没有评论,来说两句吧...