SpringBoot+shiro下通过反射扫描注解导出Controller的路径和权限信息

业务需求

项目中有非常多的api接口,很多接口都有相应的权限限制,需要把对应的权限写入到数据库的权限表中,以供选择。节省人工输入的时间。

核心逻辑

创建一个@Component类 实现 ApplicationContextAware 接口,并实现其中的setApplicationContext拿到上下文 ApplicationContext。

通过ApplicationContext 的 getBeansWithAnnotation 方法可以拿在Springboot管理下的所有带指定注解的bean。

通过bean拿到类名反射获取其中的方法,使用方法对象的 getAnnotation 方法检查是否有我们需要的注解(本例中为 RequiresPermissions.class),如果有则保存到 API_LIST 中。

注:不能直接用bean的getClass方法提供的类对象,其无法扫描到正确的方法列表

代码

Api对象

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * Api 接口
 * @author bx002
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Api implements Serializable {
    
    
    String className;
    String methodName;
    String[] path;
    String[] requiredPermissions;

}

获取Api信息


import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Api接口工具类
 * @author bx002
 */
@Slf4j
@Component
public class ApiUtils implements ApplicationContextAware {
    
    
    public final static List<Api> API_LIST = new ArrayList<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(RequestMapping.class);
        beans.forEach((name, bean) -> {
    
    
            String className = bean.getClass().getName();
            className = className.split("\\$\\$")[0];
            try {
    
    
                Class<?> clazz = Class.forName(className);
//                获取根路径
                String[] rootPath = getApiPath(clazz);
                if (rootPath == null) {
    
    
                    return;
                }
                for (Method method : clazz.getDeclaredMethods()) {
    
    
                    String[] methodPath = getApiPath(method);
                    if (methodPath == null) {
    
    
                        continue;
                    }
//                    api路径
                    List<String> pathList = new ArrayList<>();
                    for (String p1 : rootPath) {
    
    
                        for (String p2 : methodPath) {
    
    
                            pathList.add(String.format("/%s/%s", p1, p2).replace("//", "/"));
                        }
                    }
//                    api权限
                    RequiresPermissions permissions = method.getAnnotation(RequiresPermissions.class);

                    Api api = new Api();
                    api.setClassName(className)
                            .setMethodName(method.getName())
                            .setPath(pathList.toArray(new String[]{
    
    }))
                            .setRequiredPermissions(permissions != null ? permissions.value() : null)
                    ;
                    API_LIST.add(api);
                }
            } catch (ClassNotFoundException e) {
    
    
                e.printStackTrace();
            }
        });
    }

    private static String[] getApiPath(AnnotatedElement annotatedElement) {
    
    
        RequestMapping a1 = annotatedElement.getAnnotation(RequestMapping.class);
        PostMapping a2 = annotatedElement.getAnnotation(PostMapping.class);
        GetMapping a3 = annotatedElement.getAnnotation(GetMapping.class);
        if (a1 != null) {
    
    
            return a1.value();
        }
        if (a2 != null) {
    
    
            return a2.value();
        }
        if (a3 != null) {
    
    
            return a3.value();
        }
        return null;
    }
}

猜你喜欢

转载自blog.csdn.net/hjg719/article/details/116941387