2012-06-05 52 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

這是非常棒的。我會選擇這個 –

相關問題