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切面的方式。

相关推荐
IT_陈寒11 小时前
Java线程池踩了个坑,任务居然默默消失了
前端·人工智能·后端
过期动态11 小时前
【LeetCode 热题 100】找到字符串中所有字母异位词
java·数据结构·算法·leetcode·职场和发展·rabbitmq
b1305381004911 小时前
HarmonyOS开发实战:小分享-ForEach循环渲染与key生成策略
后端
程序员爱钓鱼11 小时前
配置 GoLand 与 VS Code 开发环境
前端·后端·go
程序员爱钓鱼11 小时前
Rust Vec 动态数组详解:创建、增删、遍历与排序
前端·后端·rust
超人不会飞_Jay11 小时前
Go课程2
开发语言·后端·golang
刘小八11 小时前
Spring AI Tool Calling 生产化:参数校验、权限控制与超时隔离
java·人工智能·spring
奶糖 肥晨11 小时前
一次Spring Boot编译报错排查:三元运算符与包装类型的“隐形陷阱”
java·spring boot·后端
谢栋_11 小时前
设计模式从入门到精通之(七)责任链模式
java·设计模式·责任链模式
愚公移码11 小时前
蓝凌EKP18产品:核心执行流程
java·流程引擎