你因成功而内心充满喜悦的时候,就没有时间颓废——弗兰克·迈耶
通过注解的形式,实现一个简单的接口权限限制,这里通过拦截器实现。
拦截器咱们使用HandlerInterceptorAdapter
。
首先介绍一下拦截器
:
拦截器
是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制
过滤前->拦截前->Action处理->拦截后->过滤后
用户发送请求时,先执行preHandle()方法。会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则执行用户请求的url方法。
调用了Service并返回ModelAndView,但未进行页面渲染,可以在这里继续修改ModelAndView
已经渲染了页面,在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。
注:一般使用preHandle这个拦截器进行预处理,对url进行请求拦截
介绍完拦截器
相信已经对拦截器已经有了大概的认知。
咱们现在开始自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface RoleAuth {
/**
* 功能类型
*/
String type();
}
我这里是一个很简单的注解,里面只有一个type类型。
首先咱们先介绍@Retention
注解是什么:
@Retention
的作用是定义被它所注解的注解保留多久。
咱们通过注解的源码可以清楚的看到他所需要的是一个RetentionPolicy
枚举类型值。
打开RetentionPolicy
这个枚举类之后,从注释上看:
source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。
那怎么来选择合适的注解生命周期呢?
首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解。
介绍完@Retention
之后咱们在看@Target
是什么东西:
@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)——包
@Target
里面是可以允许传入多个值,例如:@Target({ElementType.METHOD, ElementType.TYPE})
我这里选择的范围是:接口、类、枚举、注解、方法上。
介绍完注解之后,咱们就可以通过拦截器和注解(反射机制)实现通过注解拦截到用户请求。
@Component
public class RoleAuthInterceptor extends HandlerInterceptorAdapter {
}
首先新建一个类去继承HandlerInterceptorAdapter
类,并实现HandlerInterceptorAdapter
中preHandle
的方法。
//这里的意思是:如果不是映射到方法上直接通过
if (!(handler instanceof HandlerMethod)) {
return super.preHandle(request, response, handler);
}
然后通过反射的方式拿到注解里面的内容,进行业务代码实现,如果不符合要求直接抛出异常,反之return true
。
注册拦截器之后需要继承WebMvcConfigurerAdapter
,不然是不会进行拦截的。
需要重写addInterceptors方法,这里是对根目录"/"进行拦截,可以指定拦截url请求目录。
写到这里,咱们就可以通过注解的方式进行拦截了。
//放到接口上,就会被拦截该接口,进行业务判断。
@RoleAuth(type = FunctionConstant.COURSE)
这样简单自定义注解+拦截器就完事了。
最后把我最喜欢的一句话贴到这里:"人生最好的贵人,就是努力向上的自己。”生活不会辜负一个一直在努力的人。愿我们都能在各自坚持的道路上,遇见更好的自己
。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。