如何自定义注解实现拦截

1.前言

在springmvc及springboot中,注解随处可见,我们几乎每天都在跟他打交道;那么如何自定义注解呢?自定义注解会不会更香呢

2.Java注解理解

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。

3.如何自定义注解
3.1注解的分类

1.内置注解,例如@Override
2.元注解,注解其他注解的基础注解
3.自定义注解

3.2 元注解理解

一般地,常用的元注解主要有以下四个:
1.@Target
2.@Retention
3.@Documented
4.@Inhrited

@Target
修饰注解的使用范围:packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)
ElementType取值:
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention
修饰注解被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
RetentionPoicy取值
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)

@Document
用于描述其它类型的注解应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。主要表示需要在什么级别保存该注释信息

@Inhrited
@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。

3.3 如何自定义注解

1.自定义权限注解


@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Authority{
    
    
    String value() default "";
}

2.controler或service添加自定义注解

    @GetMapping("/user/info")
    @Authority("user")
    public Map<String, Object> getUserInfo() {
    
    
     ...
    }

3.实现filter,通过反射获取自定义注解的值

扫描二维码关注公众号,回复: 11875775 查看本文章
@Component
public class MyInterceptor extends HandlerInterceptorAdapter {
    
    

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
    
        if (handler instanceof HandlerMethod) {
    
    
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            Authority authority= method.getAnnotation(Authority.class);
            String value = authority.getValue();
            //获取到value进行相关的逻辑判断
            if (xxx(value)) {
    
    
               //拦截
               return false;
              }
        }
       return true;
}
}

4.注册filter

@EnableWebMvc
@Configuration
public class MyInterceptorConfigurer implements WebMvcConfigurer {
    
    
    @Autowired
    private MyInterceptor myInterceptor ;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        // 注册拦截器
        InterceptorRegistration ir = registry.addInterceptor(myInterceptor );
        // 配置拦截的路径
        ir.addPathPatterns("/**");
        // 配置不拦截的路径
        ir.excludePathPatterns("/static/**");
        // 配置不拦截的路径
        ir.excludePathPatterns("/**.html");
        // exclude ico
        ir.excludePathPatterns("/**.ico");
        ir.excludePathPatterns("/webjars/**");
    }
}

好了,自定义注解实现的前置拦截就实现呢!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zhangxing52077/article/details/108664629