2012-06-05 19 views
10

为了提供一些运行时生成的API文档,我想遍历所有的Spring MVC控制器。所有控制器都使用Spring @Controller注释进行注释。目前,我不喜欢这样写道:如何在Spring MVC中查找所有控制器?

for (final Object bean: this.context.getBeansWithAnnotation(
     Controller.class).values()) 
{ 
    ...Generate controller documentation for the bean... 
} 

但这段代码的第一个电话是EXTREMELY缓慢。我想知道Spring是否遍历类路径中的ALL类,而不是只检查定义的bean。当上面的代码运行时,控制器已经被加载,日志显示所有的请求映射,所以Spring MVC必须已经知道它们,并且必须有更快的方式来获取它们的列表。但是如何?

+0

我不知道为什么你会需要这些信息,因为你正在做的注释'@ Controller'(S)反正 – ant

+3

他提到,在这个问题很清楚,他要产生这些控制器的文档。 –

回答

16

我在几个月前也遇到过这样的需求,我用下面的代码片段实现了它。

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); 
     scanner.addIncludeFilter(new AnnotationTypeFilter(Controller.class)); 
     for (BeanDefinition beanDefinition : scanner.findCandidateComponents("com.xxx.yyy.controllers")){ 
      System.out.println(beanDefinition.getBeanClassName()); 
     } 

你也可以用你的控制器做这样的事情。

更新了代码片段。删除了不必要的代码,只显示控制器的类名,以便更好地理解。 希望这可以帮助你。干杯。

+0

好的片段(+1)。但我认为这太低了。我的意思是这一个scanns *类*。我相信'getBeansWithAnnotation()'实现应该使用里面的扫描器。 – AlexR

+0

可能你是对的。但他想要更快的方式来实现这一点。 Ans我已经使用了上面的代码片段,它对我来说不慢。这就是为什么我提出这个建议。而这个扫描器类是由Spring自己提供的,所以根据我的说法,它的级别并不低。 –

+1

与getBeansWithAnnotation()相比,效果很好,速度也快得多。谢谢! – kayahr

27

我喜欢@Japs建议的方法,但也想推荐一种替代方法。 这是基于您的观察,类路径已被Spring扫描,并且配置了控制器和请求映射方法,此映射保留在handlerMapping组件中。如果您使用的是Spring 3.1,则此handlerMapping组件是RequestMappingHandlerMapping的一个实例,您可以通过这些查询来查找handlerMappedMethods和相关的控制器(如果您使用的是较旧版本的Spring,则应该可以使用类似方法):

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 

@Controller 
public class EndpointDocController { 
 private final RequestMappingHandlerMapping handlerMapping; 
  
 @Autowired 
 public EndpointDocController(RequestMappingHandlerMapping handlerMapping) { 
  this.handlerMapping = handlerMapping; 
 } 
   
 @RequestMapping(value="/endpointdoc", method=RequestMethod.GET) 
 public void show(Model model) { 
  model.addAttribute("handlerMethods", this.handlerMapping.getHandlerMethods()); 
 } 
} 

我在这个网址http://biju-allandsundry.blogspot.com/2012/03/endpoint-documentation-controller-for.html

这提供了更多细节是基于春源的罗森Stoyanchev春3.1的介绍。

+1

这是非常棒的。我会选择这个 –

相关问题