springboot 自定义注解

一、自定义注解 定义

  • 注解类定义的关键字为 @interface
  • @Retention 定义注解的保留策略为 运行时RUNTIME,定义为运行时才能在拦截器、过滤器、切面中获取并处理业务逻辑。
  • @Target 定义注解的使用对象为 METHOD类方法。这里还可以指定多个用逗号分隔。其他类型参考查看 java.lang.annotation.ElementType,例如TYPE[@RestController、@Controller]、PARAMETER[@PathVariable]
xml 复制代码
package org.javatrip.customannotation;

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

/**
 * @author 小溪
 */
@Retention(RetentionPolicy.RUNTIME) // 定义注解的保留策略,运行时
@Target({ElementType.METHOD}) // 定义注解的类型,在方法上、类上
public @interface PermissionAnnotation {
    // 可以定义属性,这里定义了String类型的属性
    String permissionName();
    String permissionType();
    String description() default "这里是描述";
}

二、应用示例场景

xml 复制代码
package org.javatrip.customannotation;

import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AnnotationController {

    @GetMapping("/list")
    @PermissionAnnotation(permissionName = "userlist", permissionType = "get")
    public String getmissionName() {
        return "test";
    }
}

1、过滤器中拦截校验

xml 复制代码
package org.javatrip.customannotation;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.io.IOException;
import java.lang.reflect.Method;

@WebFilter(filterName = "MyFilter2", urlPatterns = "/*")
@Component
public class MyFilter2 implements Filter {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("2MyFilter init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        try {
            HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(httpServletRequest);
            if (handlerExecutionChain != null) {
                Object handler = handlerExecutionChain.getHandler();
                if (handler instanceof HandlerMethod) {
                    HandlerMethod handlerMethod = (HandlerMethod) handler;
                    Method method = handlerMethod.getMethod();
                    // 检查方法是否有MyCustomAnnotation注解
                    if (method.isAnnotationPresent(PermissionAnnotation.class)) {
                        PermissionAnnotation permissionAnnotation = method.getAnnotation(PermissionAnnotation.class);
                        // 获取注解的值
                        String name = permissionAnnotation.permissionName();
                        String type = permissionAnnotation.permissionType();
                        System.out.println("name="+name+" type="+type);

                    }
                }
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

2、拦截器中校验注解

配置拦截器

xml 复制代码
package org.javatrip.customannotation;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.lang.reflect.Method;

public class PermissionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            if(handlerMethod.hasMethodAnnotation(PermissionAnnotation.class)){
                PermissionAnnotation permissionAnnotation = handlerMethod.getMethodAnnotation(PermissionAnnotation.class);
                String name = permissionAnnotation.permissionName();
                String type = permissionAnnotation.permissionType();
                System.out.println("name="+name+" type="+type);
            }
        }
        return true;
    }
}

注册拦截器

xml 复制代码
package org.javatrip.customannotation;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new PermissionInterceptor()).addPathPatterns("/**");
    }
}

3、AOP切面校验注解

三、总结

在web应用中根据方法注解进行权限校验,推荐使用 2拦截器、3AOP切面的方式。

相关推荐
Rexi几秒前
go如何写单元测试1
后端
chxii2 分钟前
在 Spring Boot 中,MyBatis 的“自动提交”行为解析
java·数据库·mybatis
徐子童5 分钟前
数据结构----排序算法
java·数据结构·算法·排序算法·面试题
Harry技术31 分钟前
Spring Boot 4.0 发布总结:新特性、依赖变更与升级指南
spring boot·后端
xiaohua100939 分钟前
ZGC实践
java·jvm
武子康41 分钟前
大数据-159 Apache Kylin Cube 实战:Hive 装载与预计算加速(含 Cuboid/实时 OLAP,Kylin 4.x)
大数据·后端·apache kylin
蒂法就是我43 分钟前
策略模式在spring哪里用到了?
java·spring·策略模式
青衫码上行1 小时前
【Java Web学习 | 第14篇】JavaScript(8) -正则表达式
java·前端·javascript·学习·正则表达式
疯狂的程序猴1 小时前
Mac 抓包软件怎么选?从 HTTPS 调试、TCP 数据流分析到多工具协同的完整抓包方案
后端
BingoGo1 小时前
使用 PHP 和 Raylib 也可以开发贪吃蛇游戏
后端·php