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并且应用程序不会启动。