Java自定义注解@interface配合拦截器Interceptor的使用

注:文章皆为个人纪录,可用性请以最终结果为准,若有错还请大佬们指出,谢谢!

此文章可对自定义注解与拦截器进行综合学习,讲解简洁明了


步骤一:创建自定义注解 @TestDefinition 

(自定义注解我个人一般用来做标记使用,为了体现它的“属性作用”,此处仅加一个属性“value”)

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解
 *
 * Target(ElementType.METHOD) 设置自定义注解的作用类型,有类、方法、参数等
 * Retention(RetentionPolicy.RUNTIME) 设置自定义注解的生命周期,一般选择运行时
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestDefinition {
    String value() default "默认值"; // 可以定义一些属性,并可以给这些属性设默认值

    /**
     * 自定义参数
     */
    String index();

    /**
     * 自定义参数
     */
    String type();
}

源码解析:

类型与生命周期的切换分别用ElementType,RetentionPolicy对象去调就行了,查看源码发现有如下类型生命周期可供选择

/*
 * @author  Joshua Bloch
 * @since 1.5
 * @jls 9.6.4.1 @Target
 * @jls 4.1 The Kinds of Types and Values
 */
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE, // 类、接口、枚举

    /** Field declaration (includes enum constants) */
    FIELD, // 成员属性

    /** Method declaration */
    METHOD, // 方法

    /** Formal parameter declaration */
    PARAMETER, // 方法参数

    /** Constructor declaration */
    CONSTRUCTOR, // 构造器

    /** Local variable declaration */
    LOCAL_VARIABLE, // 局部变量

    /** Annotation type declaration */
    ANNOTATION_TYPE, // 注解

    /** Package declaration */
    PACKAGE, // 包
}
/*
 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang.annotation;

/**
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE, // 表示自定义注解的生命周期在源码阶段,编译后结束

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS, // 表示自定义注解的生命周期在编译阶段,运行后结束(默认这种)

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME // 表示自定义注解的生命周期在运行阶段(最常用)
}

步骤二:创建两个方法待测试时使用

由于ElementType 的类型选择了METHOD,所以@TestDefinition只能作用于方法

其中testStudy2方法使用自定义注解 @TestDefinition

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

    @RequestMapping("/testStudy1")
    public Object testStudy1() {
        log.info("没加自定义注解的方法666");
        return "666";
    }

    @RequestMapping("/testStudy2")
    @TestDefinition // ------------------使用自定义注解
    public Object testStudy2() {
        log.info("加了自定义注解的方法777");
        return "777";
    }
}

步骤三:创建拦截器StudyInterceptorTest,并制定拦截规则

说明:如果是初学者,建议将所有的拦截器写入专门放拦截器的包中,别当作普通的类瞎jb放

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 拦截器
 *
 * StudyInterceptorTest 为自定义拦截器名称
 * HandlerInterceptor 为拦截器接口(都继承这玩意儿实现方法)
 */
@Component
@Slf4j
public class StudyInterceptorTest implements HandlerInterceptor {
    /**
     * 前置拦截
     *
     * @param httpServletRequest 请求
     * @param httpServletResponse 响应
     * @param o 当前进入拦截器的对象
     * @return true放行 false拦截
     * @throws Exception 异常
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
        log.info("########### 开始进入拦截器");
        HandlerMethod handlerMethod = (HandlerMethod)handler; // 控制器方法
        Method method = handlerMethod.getMethod(); // 当前进入拦截器的方法
        TestDefinition annotation = method.getAnnotation(TestDefinition.class); // 当前进入拦截器的方法上的TestDefinition注解
        // 如果需要匹配类注解,用反射对象调用isAnnotationPresent(自定义注解.class)方法来判断类上是否用上了这个自定义注解
        // 如果需要匹配Controller的url则:if (request.getRequestURI().equalsIgnoreCase("/user/testInterceptor")) {...}
        if (annotation == null) {
            log.info("########### 放行");
            return true; // 放行
        }
        log.info("########### 拦截");
        log.info("########### 获得自定义注解中设置的参数value[{}]", annotation.value()); // 获取自定义注解中的参数
        httpServletResponse.getWriter().print("被拦截");
        return false; // 拦截
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        log.info("########### postHandle拦截器");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        log.info("########### afterCompletion拦截器");
    }
}

步骤四:创建拦截器配置类 HandlerInterceptorConfiguration

继承 WebMvcConfigurer 接口即可管理拦截器

步骤五:实现一大堆WebMvcConfigurer API

 找到 addInterceptors 方法,添加拦截器 StudyInterceptorTest  至管理器,并路径匹配规则

@Override
public void addInterceptors(InterceptorRegistry interceptorRegistry) {
        interceptorRegistry.addInterceptor(new StudyInterceptorTest()).addPathPatterns("/**"); // 路径匹配规则
        // 一个*:只匹配字符,不匹配路径(/)两个**:匹配字符,和路径(/)
        // 如 .addPathPatterns("/secure/*", "/admin/**", "/profile/**");
}

 测试:

调用未使用自定义注解的方法:testStudy1

控制台查看结果

########### 开始进入拦截器
########### 放行 
没加自定义注解的方法666
########### postHandle拦截器
########### afterCompletion拦截器

调用使用了自定义注解的方法:testStudy2

控制台查看结果

########### 开始进入拦截器 
########### 拦截 
########### 获得自定义注解中设置的参数value[默认值] 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值