首先我們都知道,Spring的IOC機制,所有的介面和service都存在一個map容器,通過BeanFactory和ApplicationContext可以拿。那麼我們可以從這個開刀.
關於Aware介面的詳細描述:SpringBoot中的Aware介面
CommandLineRunner:通過實現這個介面,重寫run方法,可以在啟動類完成後執行要做的事情,如果多個方法都繼承了CommandLineRunner介面,多個run方法都要執行,同時要有先後順序,加@Order(value = )配權重就可以了。
@Component
@Order(value = 2)
public class A implements CommandLineRunner{
@Override
public void run(String... strings) throws Exception {
}
}
@Component
@Order(value = 1)
public class B implements CommandLineRunner {
@Override
public void run(String... strings) throws Exception {
}
}
這樣,B一定會啟動成功後先於A先執行。
扯遠了,說回來,為方便直接寫:
@Override
public void run(String... args) throws Exception {
//獲取使用RestController註解標註的的所有controller類
Map<String, Object> controllers = applicationContext.getBeansWithAnnotation(RestController.class);
//遍歷每個controller層
for (Map.Entry<String, Object> entry : controllers.entrySet()) {
Object value = entry.getValue();
System.out.println("拿到controller:"+entry.getKey()+",拿到value:"+value);
Class<?> aClass = AopUtils.getTargetClass(value);
System.out.println("拿到Class:"+aClass);
}
}
可以看到找到了GoodController 和AnalysisController,但是卻沒有找到我特意舉例的一個Good2Controller
執行結果:
成功列印出來~
// 首先拿到所有的方法
List<Method> declaredMethods = Arrays.asList(aClass.getDeclaredMethods());
for (int i = 0; i < declaredMethods.size() ; i++) {
// 下面開始根據註解型別進行輸出統計
GetMapping getMapping = declaredMethods.get(i).getAnnotation(GetMapping.class);
PostMapping postMapping = declaredMethods.get(i).getDeclaredAnnotation(PostMapping.class);
System.out.println("Get相關的:"+JSON.toJSONString(getMapping));
System.out.println("Post相關的:"+JSON.toJSONString(postMapping));
}
public class EarlyWarningApplication implements ApplicationContextAware ,CommandLineRunner {
// 定義一個私有的方便本class中呼叫
private ApplicationContext applicationContext;
// 通過重寫ApplicationContextAware感知介面,將ApplicationContext賦值給當前的私有context容器
@Override
public void setApplicationContext(ApplicationContext arg0) {
this.applicationContext = arg0;
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(EarlyWarningApplication.class);
application.run(args);
}
@Override
public void run(String... args) throws Exception {
Map<String, Object> controllers = applicationContext.getBeansWithAnnotation(RestController.class);
for (Map.Entry<String, Object> entry : controllers.entrySet()) {
Object value = entry.getValue();
System.out.println("拿到controller:"+entry.getKey()+",拿到value:"+value);
Class<?> aClass = AopUtils.getTargetClass(value);
System.out.println("拿到Class:"+aClass);
RequestMapping annotation = aClass.getAnnotation(RequestMapping.class);
RequestMapping declaredAnnotation = aClass.getDeclaredAnnotation(RequestMapping.class);
List<Method> methods = Arrays.asList(aClass.getMethods());
System.out.println("Public Methods:" + methods);
List<Method> declaredMethods = Arrays.asList(aClass.getDeclaredMethods());
for (int i = 0; i < declaredMethods.size() ; i++) {
GetMapping getMapping = declaredMethods.get(i).getAnnotation(GetMapping.class);
PostMapping postMapping = declaredMethods.get(i).getDeclaredAnnotation(PostMapping.class);
System.out.println("Get相關的:"+JSON.toJSONString(getMapping));
System.out.println("Post相關的:"+JSON.toJSONString(postMapping));
}
}
}
}
@Autowired
WebApplicationContext applicationContext;
@GetMapping("/getParam")
public String getParam(){
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
// 拿到Handler介面卡中的全部方法
Map<RequestMappingInfo, HandlerMethod> methodMap = mapping.getHandlerMethods();
List<String> urlList = new ArrayList<>();
for (RequestMappingInfo info : methodMap.keySet()){
Set<String> urlSet = info.getPatternsCondition().getPatterns();
// 獲取全部請求方式
Set<RequestMethod> Methods = info.getMethodsCondition().getMethods();
System.out.println(Methods.toString());
for (String url : urlSet){
// 加上自己的域名和埠號,就可以直接呼叫
urlList.add("http://localhost:XXXX"+url);
}
}
return urlList.toString();
}