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

相关推荐
苏-言5 分钟前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
界面开发小八哥13 分钟前
更高效的Java 23开发,IntelliJ IDEA助力全面升级
java·开发语言·ide·intellij-idea·开发工具
草莓base26 分钟前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Allen Bright39 分钟前
maven概述
java·maven
Ljw...41 分钟前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改
编程重生之路41 分钟前
Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常
java·spring boot·后端
薯条不要番茄酱42 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
努力进修1 小时前
“探索Java List的无限可能:从基础到高级应用“
java·开发语言·list
politeboy1 小时前
k8s启动springboot容器的时候,显示找不到application.yml文件
java·spring boot·kubernetes
Daniel 大东2 小时前
BugJson因为json格式问题OOM怎么办
java·安全