0.定义
注解是一种能被添加到java源代码中的元数据,方法、类、参数和包都可以用注解来修饰。注解可以看作是一种特殊的标记,可以用在方法、类、参数和包上,程序在编译或者运行时可以检测到这些标记而进行一些特殊的处理。
(1)创建一个注解的基本元素
修饰符
访问修饰符必须为public,不写默认为pubic;
关键字
关键字为@interface;
注解名称
注解名称为自定义注解的名称,例如上面的XinLinLog 就是注解名称
注解类型元素
注解类型元素是注解中内容,根据需要标志参数,例如上面的注解的value;
(2)元注解(@Target、@Retention、@Inherited、@Documented)
我们上面的创建的注解XinLinLog上面还有几个注解(@Target、@Retention、@Inherited、@Documented),这四个注解就是元注解,元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的元注解类型,它们被用来提供对其它 注解类型作标志操作(可以理解为最小的注解,基础注解)
@Target:用于描述注解的使用范围,该注解可以使用在什么地方
类型 | 描述 |
ElementType.TYPE | 应用于类、接口(包括注解类型)、枚举 |
ElementType.FIELD | 应用于属性(包括枚举中的常量) |
ElementType.METHOD | 应用于方法 |
ElementType.PARAMETER | 应用于方法的形参 |
ElementType.CONSTRUCTOR | 应用于构造函数 |
ElementType.LOCAL_VARIABLE | 应用于局部变量 |
ElementType.ANNOTATION_TYPE | 应用于注解类型 |
ElementType.PACKAGE | 应用于包 |
@Retention:表明该注解的生命周期
生命周期类型 | 描述 |
RetentionPolicy.SOURCE | 编译时被丢弃,不包含在类文件中 |
RetentionPolicy.CLASS | JVM加载时被丢弃,包含在类文件中,默认值 |
RetentionPolicy.RUNTIME | 加载,包含在类文件中,在运行时可以被获取到 |
@Inherited:是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
@Documented:表明该注解标记的元素可以被Javadoc 或类似的工具文档化
1.常见自定义注解
上面总结的注解的定义,但是创建这样一个注解,仅仅是一个标志,装饰类、方法、属性的,并没有功能,要想实现功能,需要我们通过拦截器、AOP切面这些地方获取注解标志,然后实现我们的功能。
注意:后面介绍的很多注解有第三方框架已经实现了,如果不想自定义可以直接使用第三方框架,如果第三方框架不能满足自己项目的需求,则可以考虑自定义框架。
(1)身份验证注解
有的时候我们访问后台接口的时候,存在一个简单逻辑:有的接口用户没有登录的情况下是不允许访问的。比如获取用户数据的一个接口,如果用户根本没有登录,那么当前这个接口是根本不能访问的。有的接口用户不登录也要允许获取数据,比如验证码。
shiro框架中的@RequiresAuthentication 注解就可以简单实现这个功能。
(2)角色权限注解
除了上面判断当前这个接口是否需要登录才能访问,有的接口还需要判断哪些角色才有权限来访问。比如用的接口只允许管理员访问,而有的接口只允许某个角色来访问(比如’学生’,’老师’等)。
shiro框架中的@RequiresRoles注解就可以简单实现实现这个功能。比如下面这样:
@RequiresRoles(value = {"root","admin"})
(3)字段属性注入注解
字段属性注入就是在实例化对象时,同时向对象中的属性进行相应的赋值。
即,通俗点说,字段属性注入就是给类中的属性赋值。
(4)对象的属性校验注解
这个功能主要用来校验对象的某些属性是否符合要求,比如是否为空,手机号码是否符合要求等。
validation这个包中@Valid注解就具备这个功能。
@Valid注解基础用法如下:
public class User{
@NotBlank(message = "姓名不为空")
private String username;
@NotBlank(message = "密码不为空")
private String password;
}
如果嵌套的实体对象,则需要在最外层属性上添加@Valid注解
public class User{
@NotBlank(message = "姓名不为空")
private String username;
@NotBlank(message = "密码不为空")
private String password;
//嵌套必须加@Valid,否则嵌套中的验证不生效
@Valid
@NotNull(message = "用户信息不能为空")
private UserInfo userInfo;
}
如果觉得上面的功能不够用,也可以自定义对象的属性校验注解。
(5)操作日志注解
这个注解可能是自定义最多的,有时候我们访问接口时,需要记录下用的用户名、操作的接口、提交的参数、操作的内容、隶属模块、操作时间等等。虽然现在的已经有很多第三方日志框架了,但是因为每个项目的内容不同,需要记录的操作日志也不同,所以很多项目需要自定义操作日志注解。
(6)缓存注解
使用这个注解的场景是:有的时候我们需要往缓存中存取数据,这个逻辑是如果缓存中如果有这个数据了,那么就直接取,如果没有这个数据,那么就直接存进去。
spring当中里面已经有一个@Cacheable注解,已经实现了此功能,如果觉得不够用可以自定义这个注解。
类似的跟缓存有关的注解还有@CachePut、@CacheEvict、@CacheConfig、@Caching等
(7)防刷注解
也是比较常用的注解,有些人总会去无限次的请求接口,比如暴力测试登录接口,这时候就有必要在这个接口上加一些限制,比如1秒至多请求三次等,限制某IP提交等。
(8)动态切换数据源注解
有的项目有多个数据源,不同的接口可能要从不同的数据库存取数据,这个时候我们可以通过自定义注解实现访问不同的数据源。