Spring Boot常用注解(一) - 元注解

看到一篇总结的不错的文章:

转载: 深入理解Java注解

1.@Target

@Target – 表示该注解用于什么地方,枚举类型ElementType 表示@Target作用位置

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {

    ElementType[] value();
}

public enum ElementType {
    TYPE,   // 类,接口(包括注解类型)或枚举声明

    FIELD,  // 字段声明(包括枚举常量)

    METHOD, // 方法声明

    PARAMETER,  // 方法参数

    CONSTRUCTOR,  // 构造方法

    LOCAL_VARIABLE,  // 局部变量

    ANNOTATION_TYPE, // 注解类型

    PACKAGE,  // 包

    TYPE_PARAMETER, 

    TYPE_USE
}

@Target的使用:

@Target只有一个方法,默认为value(),返回一个ElementType类型数组
所以使用时既可以带参数名,也可以不带参数名,参数为数组用花括号表示
1. @Target(ElementType.ANNOTATION_TYPE)
2. @Target(value = {ElementType.TYPE})
3. @Target({}) // 不能用来注解任何东西
4. @Target(value = {ElementType.TYPE,ElementType.METHOD})

2.@Retention

@Retention – 定义该注解的生命周期

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {

    RetentionPolicy value();
}


package java.lang.annotation;

public enum RetentionPolicy {

    SOURCE, // 仅出现在源代码中,在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。

    CLASS,  // 被编译在class文件中,但在运行时不需要由JVM保留。在字节码文件的处理中有用。注解默认使用这种方式

    RUNTIME // 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式
}

@Retention的使用:

@Retention只有一个方法,返回RetentionPolicy类型,所以直接这样使用
@Retention(RetentionPolicy.RUNTIME)

3.@Documented

@Documented是一个标记注解,没有方法,用于描述其它类型的annotation应该被作为被标注的程序成员的公共API

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

4.@Inherited

@Inherited是一个标记注解,没有方法,是否允许子类继承该注解
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

5.JDK8 @Repeatable

1.8之前的 JDK 并不允许开发者在同一个声明式前加注同样的 Annotation,(即使属性值不同)这样的代码在编译过程中会提示错误。而 Java 8 解除了这一限制,提供了@Repeattable注解:

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    Class<? extends Annotation> value();
}
  1. @Repeatable参数为:类名.class
  2. @Repeatable(c.class)作用在注解annotation上,注解annotation就可以重复标注
/**
 * UserRoles中必须定义返回数组类型的 value 方法
 * 数组中元素的类型必须为对应的 Repeating Annotation 类型
 * */
public @interface UserRoles {
    UserRole[] value();
}

/**
 * @Repeatable 标签后括号中的值即为指定的Annotation 的类型
 * Java编译器会把重复的UserRole对象保存到UserRoles中
 * */
@Repeatable(UserRoles.class)
public @interfa UserRole {
    String role();
}

/**
 * 一个人有多种角色:
 * 1.父母的儿子
 * 2.老师的学生
 * */
@UserRole(role="son")
@UserRole(role="student")
public class User {

}

6.自定义注解

注解定义格式:

public @interface 注解名 {定义体}

定义一个注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Todo {
    public enum Priority {LOW, MEDIUM, HIGH}
    public enum Status {STARTED, NOT_STARTED}

    //定义属性
    String value() default "";
    Priority priority() default Priority.LOW;
    Status status() default Status.NOT_STARTED;
}
  1. 注解只有方法,没有成员,方法必须是public的,去掉public,默认也是public,因为注解也是一个接口interface
  2. 注解方法必须有返回类型:返回值类型只能是基本类型、Class、String、enum
  3. 注解方法运行提供默认值,但不是必需的
  4. 一个注解方法其实就是一个参数,方法名就是参数名
  5. 当注解没有方法时,即没有参数,表示一个标记注解
  6. 当注解有一个方法时,即一个参数,最好把方法名改为“value”,这是默认的
  7. 当使用自定义的注解时,参数类型可能是基本类型、Class、String、enum或者数组,如果是数组,通过paramname={value1,value2}传入

使用自定义注解:

如果注解中只有一个方法,即一个参数,可以直接命名为“value”,使用时无需再标明属性名

@interface Author {
    String value();
}


@Author("lipingan")
public void someMethod() {
}

如果注解方法返回类型(参数类型)为数组,格式如@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {

    int value() default 1234;
}

如果注解中有多个方法,即使用时有多个参数,格式为 参数名=参数值

@Todo(priority = Todo.Priority.MEDIUM, author = "李平安", status = Todo.Status.STARTED)
public void testAnnotation() {
    //其他代码
}

7.注解处理器类库

定义了注解,并在需要的时候给相关类,类属性加上注解信息,如果没有响应注解信息处理流程,注解可以说是没有实用价值。如何让注解真真的发挥作用,主要就在于注解处理方法,Java SE5扩展了反射机制的API,以帮助快速的构造自定义注解处理器

Java在java.lang.reflect 包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素
java.lang.reflect.AnnotatedElement
这里写图片描述

该接口主要有如下几个实现类:

   Class:类定义
  Constructor:构造器定义
  Field:累的成员变量定义
  Method:类的方法定义
  Package:类的包定义

当一个Annotation类型被定义为运行时的Annotation后,该注解才能是运行时可见,AnnotatedElement 接口的实现(Class、Method和Constructor)通过Annotation接口的四个方法可以获取该实现上的注解信息

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值