扫描项目中所有包含某注解的方法及获取其URI

获取到包含某注解的所有类

首先先要获取到applicationContext
只要类 implements ApplicationContextAware就会自动注入到类里的applicationContext
话不多说直接上代码

@Component
@Slf4j
public class test implements ApplicationContextAware {

	private static ApplicationContext applicationContext;
	
	public void test(Class<? extends Annotation> annotation){
		List<Class<?>> inClassList = new ArrayList<>();
		Map<Class<?>, Set<Method>> containsMap = new HashMap<>();
		//获取到所有包含@RestController 或者 @Controller的bean
		Map<String, Object> beanList = applicationContext.getBeansWithAnnotation(RestController.class);
		beanList.putAll(applicationContext.getBeansWithAnnotation(Controller.class));
		beanList.forEach((k, v) -> inClassList.add(applicationContext.getType(k)));
		getClassesWithAnnotationFromAllClasses(inClassList, annotation,  containsMap);
	}
}

inClassList里就可以获取到所有的包含@RestController 或者 @Controller 的bean了

获取类集合里所有包含自定义注解的方法名

/**
     * 获取类里所有包含annotation的方法名
     *
     * @param inClassList  需过滤其中方法的class集合
     * @param annotation   注解class
     * @param map          包含该annotation的map,key为controller类,集合中为方法
     */
    private void getMethodsWithAnnotationFromAllClasses(List<Class<?>> inClassList,
                                                        Class<? extends Annotation> annotation, Map<Class<?>, Set<Method>> map) {
        for (Class<?> myClasss : inClassList) {
            Method[] methods = myClasss.getMethods();
            Set<Method> methodList = new HashSet<>();
            for (Method method : methods) {
            //findAnnotation也可以拿到其父类是否包含该注解
                if (null != method && null != AnnotationUtils.findAnnotation(method, annotation)) {
                    try {
                        methodList.add(method);
                    }catch (Exception e){
                        log.error(e.toString());
                    }
                }
            }

            if (methodList.size() > 0) {
                map.put(myClasss, methodList);
            }

        }

获取所有包含某注解的方法及获取其URI

最后一步就是获取方法的URI了,直接把完整的代码贴出来

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;


@Component
@Slf4j
public class test implements ApplicationContextAware {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    private static ApplicationContext applicationContext;

    public Set<String[]> test(Class<? extends Annotation> annotation) {
        List<Class<?>> inClassList = new ArrayList<>();
        Map<Class<?>, Set<Method>> containsMap = new HashMap<>();
        //获取到所有包含@RestController 或者 @Controller的bean
        Map<String, Object> beanList = applicationContext.getBeansWithAnnotation(RestController.class);
        beanList.putAll(applicationContext.getBeansWithAnnotation(Controller.class));
        beanList.forEach((k, v) -> inClassList.add(applicationContext.getType(k)));
        getMethodsWithAnnotationFromAllClasses(inClassList, annotation, containsMap);
        Set<String[]> resultList = new HashSet<>();
        //获取所有uri的集合
        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : map.entrySet()) {
            HandlerMethod method = entry.getValue();
            for (Map.Entry<Class<?>, Set<Method>> classEntry : containsMap.entrySet()) {
                Set<Method> str = classEntry.getValue();
                Set<String> methodNameSet = str.stream().map(Method::getName).collect(Collectors.toSet());
                //如果controller匹配到了containsMap的key且方法存在于containsMap的value里,将其uri加入resultList
                String controllerName = classEntry.getKey().getName();
                String methodName = method.getBeanType().getName();
                //controllerName拿到的是代理beanName,需要处理
                if (controllerName.contains("$$")) {
                    controllerName = controllerName.substring(0, controllerName.indexOf("$$"));
                }
                try {
                    if (controllerName.equals(methodName) && methodNameSet.contains(method.getMethod().getName())) {
                        //获取uri
                        for (RequestMethod m : entry.getKey().getMethodsCondition().getMethods()) {
                            for (String pattern : entry.getKey().getPatternsCondition().getPatterns()) {
                                String[] resultArr = new String[2];
                                resultArr[0] = m.name();
                                resultArr[1] = pattern;
                                resultList.add(resultArr);
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error(e.toString());
                }
            }
        }
        return resultList;
    }

    /**
     * 获取类里所有包含annotation的方法名
     *
     * @param inClassList 需过滤其中方法的class集合
     * @param annotation  注解class
     * @param map         包含该annotation的map,key为controller类,集合中为方法
     */
    private void getMethodsWithAnnotationFromAllClasses(List<Class<?>> inClassList,
                                                        Class<? extends Annotation> annotation, Map<Class<?>, Set<Method>> map) {
        for (Class<?> myClasss : inClassList) {
            Method[] methods = myClasss.getMethods();
            Set<Method> methodList = new HashSet<>();
            for (Method method : methods) {
                //findAnnotation也可以拿到其父类是否包含该注解
                if (null != method && null != AnnotationUtils.findAnnotation(method, annotation)) {
                    try {
                        methodList.add(method);
                    } catch (Exception e) {
                        log.error(e.toString());
                    }
                }
            }

            if (methodList.size() > 0) {
                map.put(myClasss, methodList);
            }

        }

    }
}

使用ApplicationRunner以在容器启动完成的时候获取列表

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class ServiceStarted implements ApplicationRunner {
    @Autowired
    Test test;
    @Override
    public void run(ApplicationArguments args){
        Set<String[]> sets = test.test(TestAnnotation.class);
        log.info("获取到列表{}",sets);
        //dosomething
    }
}

拿到列表后就可以dosomething了,保存到本地文件夹、保存至redis、或者也可以在这一步进行对类操作,都可以
set[0] 为method 即 POST GET DELETE
set [1] 为该方法的uri

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot是一个基于Spring框架的快速开发的框架,它的注解非常丰富,可以用来配置和控制Spring Boot应用程序的各种方面。下面是一些常用的Spring Boot注解及其解析。 1. @SpringBootApplication 这是Spring Boot应用程序的主要注解,它包含了@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解。其@Configuration用于定义配置类,@EnableAutoConfiguration用于自动配置Spring Boot应用程序,@ComponentScan用于扫描组件。 2. @RestController @RestController用于定义RESTful Web服务,它是@Controller和@ResponseBody的组合注解。@Controller用于定义控制器,@ResponseBody用于返回数据。 3. @RequestMapping @RequestMapping用于定义Web请求的映射关系,它可以用于类或方法级别。在类级别上,它定义了一组请求映射,而在方法级别上,它定义了一个具体的请求映射。 4. @PathVariable @PathVariable用于从URI提取变量值,它可以用于方法参数上。 5. @RequestParam @RequestParam用于从请求参数提取变量值,它也可以用于方法参数上。 6. @RequestBody @RequestBody用于将请求体的JSON或XML数据转换为Java对象,它也可以用于方法参数上。 7. @ResponseStatus @ResponseStatus用于定义响应状态码,它可以用于控制器方法上。 8. @ExceptionHandler @ExceptionHandler用于定义异常处理程序,它可以用于控制器类或方法上。 9. @Autowired @Autowired用于自动装配依赖,它可以用于属性、构造方法方法参数上。 10. @Value @Value用于注入配置属性值,它可以用于属性或方法参数上。 以上是一些常用的Spring Boot注解及其解析,当然还有很多其他的注解,可以根据具体情况选择使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值