最近看项目代码的时候看到了前辈们的写的自定义注解,决定深入的学习一下自定义注解相关的知识。
1 注解知识介绍
1.1 注解的定义
一般在项目中声明在annotation包中,声明用@interface表示
public @interface BussinessLog {
.........
}
1.2 元注解介绍
元注解的作用就是负责注解其他注解。
常见的有四种注解:
1.2.1 @Inherited
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。
比如,注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。
1.2.2 @Retention
用来说明该注解类的生命周期。
@Retention(RetentionPolicy.SOURCE)
//注解只在源码阶段保留,在编译器完整编译之后,它将被丢弃忽视
@Retention(RetentionPolicy.CLASS)
//默认,注解只被保留到编译进行的时候,它并不会被加载到 JVM 中
@Retention(RetentionPolicy.RUNTIME)
//注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们,大部分的注解都是 RUNTIME 的生命周期。
1.2.3 @Target
表明注解的作用目标
@Target(ElementType.TYPE) // 接口、类、枚举、注解
@Target(ElementType.FIELD) // 字段、枚举的常量
@Target(ElementType.METHOD) // 方法
@Target(ElementType.PARAMETER) // 方法参数
@Target(ElementType.CONSTRUCTOR) // 构造函数
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE) // 注解
@Target(ElementType.PACKAGE) // 包
1.2.4 @Document
@Documented 是一个简单的标记注解,表示是否将注解信息添加在 Java 文档,即 Javadoc 中。
1.3 注解的属性
可以查看@RequestMapping的源码:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以无形参的方法形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。
注解可以有默认值,需要用 default 关键字指定
2 自定义注解示例
自定义@permission注解
/**
* 权限注解 用于检查权限 规定访问权限
*
* @example @Permission({role1,role2})
* @example @Permission
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Permission {
/**
* <p>角色英文名称</p>
* <p>使用注解时加上这个值表示限制只有某个角色的才可以访问对应的资源</p>
* <p>常用在某些资源限制只有超级管理员角色才可访问</p>
*/
String[] value() default {};
}
3 注解的使用
@Permission(Const.ADMIN_NAME)
@RequestMapping(value = "/edit")
@ResponseBody
public Tip edit(BindingResult result) {
if (result.hasErrors()) {
throw new GunsException(ExceptionEnum.REQUEST_NULL);
}
this.menuService.updateById(menu);
return SUCCESS_TIP;
}