2012-06-05 13 views
10

Per fornire una documentazione API generata in fase di runtime, desidero eseguire un'iterazione su tutti i controller Spring MVC. Tutti i controller sono annotati con l'annotazione Spring @Controller. Attualmente lo faccio in questo modo:Come trovare tutti i controller in Spring MVC?

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

Ma la prima chiamata di questo codice è ESTREMAMENTE lento. Mi chiedo se Spring ignori le classi ALL nel classpath invece di controllare solo i bean definiti. I controller sono già caricati quando viene eseguito il codice precedente, il log li mostra tutti con i relativi mapping delle richieste, quindi Spring MVC deve già conoscerli tutti e deve esserci un modo più rapido per ottenere un elenco di essi. Ma come?

+0

Mi chiedo perché avresti bisogno di quelle informazioni, dato che stai facendo l'annotazione di '@ Controller' (s) in ogni caso – ant

+3

Ha detto che nella domanda molto chiaramente che vuole generare la documentazione per quei controller. –

risposta

16

Ho anche riscontrato tale requisito prima di alcuni mesi e l'ho raggiunto utilizzando il seguente frammento di codice.

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

Si può anche fare qualcosa del genere con i controller.

Aggiornato lo snippet di codice. Rimosso il codice non necessario e semplicemente visualizzando il nome della classe dei controller per una migliore comprensione. Spero che questo ti aiuti. Saluti.

+0

Buono snippet (+1). Ma penso che sia troppo basso. Voglio dire questo scansiona * classi *. Credo che l'implementazione di 'getBeansWithAnnotation()' dovrebbe usare lo scanner all'interno. – AlexR

+0

Forse hai ragione. Ma lui vuole un modo più veloce per raggiungere questo obiettivo. Ans Ho usato lo snippet di codice sopra riportato e non è lento per me. Ecco perché l'ho suggerito. E questa classe di scanner è fornita da Spring stessa quindi secondo me il suo livello non è basso. –

+1

Funziona alla grande e MOLTO più velocemente di getBeansWithAnnotation(). Grazie! – kayahr

27

Mi piace l'approccio suggerito da @Japs, ma vorrei anche raccomandare un approccio alternativo. Questo è basato sulla tua osservazione che il classpath è già stato scansionato da Spring, e i controller ei metodi mappati a richiesta configurati, questa mappatura è mantenuta in un componente handlerMapping. Se si utilizza Spring 3.1 questo componente handlerMapping è un'istanza di RequestMappingHandlerMapping, che è possibile eseguire una query per trovare i parametri handlerMappedMethods e i controller associati, seguendo queste linee (se si utilizza una versione precedente di Spring, si dovrebbe essere in grado di utilizzare un simile approccio):

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

ho fornito ulteriori dettagli su questo a questo indirizzo http://biju-allandsundry.blogspot.com/2012/03/endpoint-documentation-controller-for.html

questo si basa su una presentazione su Spring 3.1 da Rossen Stoyanchev di Spring Sorgente.

+1

questo è davvero fantastico. Vorrei andare con questo –

Problemi correlati