扫描项目中所有包含某注解的方法及获取其URI
springboot扫描所有包含某注解的方法及获取其URI获取到包含某注解的所有类获取类集合里所有包含自定义注解的方法名获取所有包含某注解的方法及获取其URI使用ApplicationRunner以在容器启动完成的时候获取列表获取到包含某注解的所有类首先先要获取到applicationContext只要类 implements ApplicationContextAware就会自动注入到类里的ap
·
springboot扫描所有包含某注解的方法及获取其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
更多推荐
已为社区贡献1条内容
所有评论(0)