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

相关推荐
葫芦和十三2 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp3 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑3 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯4 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan6 小时前
多Agent之间的区别
后端
青石路8 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充9 小时前
1.面向对象设计思想
后端
IT_陈寒9 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro9 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗10 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端