Come trovare tutti i controller in Spring MVC?

Per fornire una documentazione API runtime generata, voglio 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:

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

Ma la prima chiamata di questo codice è ESTREMAMENTE Lenta. Mi chiedo se Spring itera su TUTTE le classi 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?

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

Puoi anche fare qualcosa del genere con i tuoi controller.

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

Mi piace l’approccio suggerito da @Japs, ma vorrei anche raccomandare un approccio alternativo. Ciò si basa sulla tua osservazione che il classpath è già stato scansionato da Spring, e che i controllori e i metodi associati alla richiesta sono stati configurati, questa mapping è mantenuta in un componente handlerMapping . Se si utilizza Spring 3.1 questo componente handlerMapping è un’istanza di RequestMappingHandlerMapping, che è ansible 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 maggiori dettagli al riguardo su questo URL http://biju-allandsundry.blogspot.com/2012/03/endpoint-documentation-controller-for.html

Questo è basato su una presentazione sulla spring 3.1 di Rossen Stoyanchev di Spring Source.