reflection性地获取匹配特定URL的Spring MVC控制器列表

如何reflection获取所有控制器的列表(最好,如果不仅注释,但也在xml中指定),匹配Spring MVC应用程序中的一些特定URL?

在仅注释的情况下,

@Autowired private ListableBeanFactory listableBeanFactory; ... whatever() { Map beans = listableBeanFactory.getBeansWithAnnotation(RequestMapping.class); // iterate beans and compare RequestMapping.value() annotation parameters // to produce list of matching controllers } 

可以使用,但在更一般的情况下,当在spring.xml配置中指定控制器时,该怎么办? 以及如何处理请求路径参数?

从Spring 3.1开始,有RequestMappingHandlerMapping类,它提供有关@Controller类的映射( RequestMappingInfo )的信息。

 @Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping; @PostConstruct public void init() { Map handlerMethods = this.requestMappingHandlerMapping.getHandlerMethods(); for(Entry item : handlerMethods.entrySet()) { RequestMappingInfo mapping = item.getKey(); HandlerMethod method = item.getValue(); for (String urlPattern : mapping.getPatternsCondition().getPatterns()) { System.out.println( method.getBeanType().getName() + "#" + method.getMethod().getName() + " <-- " + urlPattern); if (urlPattern.equals("some specific url")) { //add to list of matching METHODS } } } } 

重要的是,在定义控制器的spring上下文中定义此bean。

通过调用HandlerMapping.getHandler(HTTPServletRequest).getHandler()获得映射的Controller。 IoC可以获取HandlerMapping实例。 如果您没有HTTPServletRequest,则可以使用MockHttpServletRequest构建Request。

 @Autowired private HandlerMapping mapping; public Object getController(String uri) { MockHttpServletRequest request = new MockHttpServletRequest("GET", uri); // configure your request to some mapping HandlerExecutionChain chain = mapping.getHandler(request); return chain.getHandler(); } 

对不起,我现在读到你想要一个URL的所有控制器。 这将使您只有一个完全匹配的控制器。 这显然不是你想要的。

您可以尝试使用ListableBeanFactory接口来检索所有bean名称。

 private @Autowired ListableBeanFactory beanFactory; public void doStuff() { for (String beanName : beanFactory.getBeanDefinitionNames()) { if (beanName.startsWith("env")) { // or whatever check you want to do Object bean = beanFactory.getBean(beanName) // .. do something with it } } } 

请在此处查看ListableBeanFactory的文档。 该接口提供了几个方法,如getBeansOfType(),getBeanDefinitionCount()等。

如果此方法未列出@Controller注释bean, 请访问此页面以了解如何完成此操作。

您需要在调度程序servlet中为RequestMappingHandlerMapping执行一个条目

    

调度程序servlet将查看此映射并在应用程序中实例化一个bean RequestMappingHandlerMapping

现在您可以使用任何控制器/类

 @Autowired private HandlerMapping mapping; 

它应该工作正常。

注意:你需要注意添加bean,如果你的任何dispatcherservlet(在大应用程序的情况下)包含这个bean,它将导致noUniqueBeanexception并且应用程序不会启动。