2012-06-05 5 views
10

Um eine Laufzeit generierte API Dokumentation zur Verfügung zu stellen, möchte ich über alle Spring MVC Controller iterieren. Alle Controller sind mit der Annotation Spring @Controller versehen. Zur Zeit mache ich es wie folgt aus:Wie finden Sie alle Steuerungen in Spring MVC?

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

Aber der erste Aufruf dieses Codes ist EXTREM langsam. Ich frage mich, ob Spring über ALLE Klassen im Klassenpfad iteriert, anstatt nur die definierten Beans zu überprüfen. Die Controller sind bereits geladen, wenn der obige Code ausgeführt wird. Das Protokoll zeigt alle mit ihren Anforderungszuordnungen an, sodass Spring MVC sie alle bereits kennen muss und es einen schnelleren Weg geben muss, um eine Liste von ihnen zu erhalten. Aber wie?

+0

Ich frage mich, warum würden Sie diese Info benötigen, da Sie die Anmerkung von '@ Controller' (s) sowieso tun – ant

+3

Er hat in der Frage sehr deutlich erwähnt, dass er die Dokumentation für diese Controller generieren möchte. –

Antwort

16

Ich bin auch auf solche Anforderung vor einigen Monaten gestoßen und ich habe es mit dem folgenden Code-Snippet erreicht.

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()); 
     } 

Sie können auch so etwas mit Ihren Controllern machen.

Das Code-Snippet wurde aktualisiert. Der nicht benötigte Code wurde entfernt und nur der Klassenname der Controller zum besseren Verständnis angezeigt. Hoffe das hilft dir. Prost.

+0

Gutes Schnipsel (+1). Aber ich denke, dass es zu niedrig ist. Ich meine, das scannt * Klassen *. Ich glaube, dass 'getBeansWithAnnotation()' Implementierung Scanner innen benutzen sollte. – AlexR

+0

Vielleicht haben Sie Recht. Aber er will einen schnelleren Weg, dies zu erreichen. Ans Ich habe das obige Code-Snippet benutzt und es ist nicht langsam für mich. Deshalb habe ich das vorgeschlagen. Und diese Scannerklasse wird von Spring selbst zur Verfügung gestellt, daher ist es meines Erachtens kein niedriges Niveau. –

+1

Funktioniert großartig und viel schneller als getBeansWithAnnotation(). Vielen Dank! – kayahr

27

Ich mag den von @Japs vorgeschlagenen Ansatz, würde aber auch einen alternativen Ansatz empfehlen. Dies basiert auf Ihrer Beobachtung, dass der Klassenpfad bereits von Spring gescannt wurde und die Controller und die request mapped Methoden konfiguriert wurden. Diese Zuordnung wird in einer Komponente handlerMapping verwaltet. Wenn Sie Spring 3.1 verwenden, ist diese handlerMapping Komponente eine Instanz von RequestMappingHandlerMapping, die Sie abfragen können, um die handlerMappedMethods und die zugehörigen Controller in diesen Zeilen zu finden (wenn Sie eine ältere Version von Spring verwenden, sollten Sie eine ähnliche Version verwenden) Ansatz):

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()); 
 } 
} 

ich an dieser uRL zur Verfügung gestellt haben dazu mehr Details http://biju-allandsundry.blogspot.com/2012/03/endpoint-documentation-controller-for.html

Dies wird auf eine Präsentation zum Spring 3.1 von Rossen Stoyanchev of Spring Quelle basiert.

+1

das ist ziemlich genial. Ich würde mit diesem gehen –