2015-03-17 12 views
16

ho creato un'applicazione di avvio di primavera con un contesto genitore (servizi) e il contesto bambino (controllori primavera-webmvc):L'utilizzo di più dispatcher servlet/contesti web con avvio primavera

@Configuration 
public class MainApiApplication { 

    public static void main(String[] args) { 
     new SpringApplicationBuilder() 
       .parent(Services.class) 
       .child(ApiOne.class, MainApiApplication.class) 
       .run(args); 
    } 

    @Bean 
    public EmbeddedServletContainerFactory servletContainer() { 
     return new TomcatEmbeddedServletContainerFactory(); 
    } 

} 

Ora voglio aggiungere un altro client contesto (e DispatcherServlet) per la mia configurazione ApiTwo.class. Penso di avere a che fare due cose:

  1. Spostare il servletContainer (in tal modo la configurazione MainApiApplication.class) fuori del contesto bambino e
  2. aggiungere un mapping di percorso/un/-> ApiOne.class e/due/ApiTwo.class

Qual è il modo di avvio a molla per farlo?

risposta

19

Come già detto @ josh-ghiloni, è necessario registrare un ServletRegistrationBean per ogni contesto Web isolato che si desidera creare. È necessario creare un contesto applicazione da una classe di configurazione xml o java. È possibile utilizzare l'annotazione @Import e @ComponentScan per aggiungere servizi condivisi al contesto padre. Ecco un esempio:

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.context.embedded.ServletRegistrationBean; 
import org.springframework.context.annotation.Bean; 
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; 
import org.springframework.web.context.support.XmlWebApplicationContext; 
import org.springframework.web.servlet.DispatcherServlet; 


//@ComponentScan({"..."}) 
//@Import({}) 
public class Starter { 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Starter.class, args); 
    } 

    @Bean 
    public ServletRegistrationBean apiV1() { 
     DispatcherServlet dispatcherServlet = new DispatcherServlet(); 

     XmlWebApplicationContext applicationContext = new XmlWebApplicationContext(); 
     applicationContext.setConfigLocation("classpath:/META-INF/spring/webmvc-context.xml"); 
     dispatcherServlet.setApplicationContext(applicationContext); 

     ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/1/*"); 
     servletRegistrationBean.setName("api-v1"); 

     return servletRegistrationBean; 
    } 

    @Bean 
    public ServletRegistrationBean apiV2() { 
     DispatcherServlet dispatcherServlet = new DispatcherServlet(); 

     AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); 
     applicationContext.register(ResourceConfig.class); 
     dispatcherServlet.setApplicationContext(applicationContext); 

     ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/2/*"); 
     servletRegistrationBean.setName("api-v2"); 
     return servletRegistrationBean; 
    } 
} 
+0

Originariamente volevo dividere la taglia perché @ josh-ghiloni ha pubblicato l'idea iniziale ma il tuo post è più completo. Perché lo scopo di SO è quello di avere una risposta definitiva a una domanda che io concedo a te. Grazie! L'unica parte mancante nel tuo esempio è aggiungere il contesto Services.class, potresti aggiungerlo a @ksokol? – Jan

+0

Ho upvoted @ josh-ghiloni per indicare la sua risposta corretta. Per aggiungere servizi al contesto genitore è necessario aggiungere '@Import ({ServiceConfig1.class, ServiceConfig2.class})' o '@ComponentScan (" my.package.service ")'. Dai uno sguardo alle prime righe nel mio esempio. –

8

Creare un ServletRegistrationBean che dichiara il servlet e le sue associazioni. Si avrà probabilmente anche voler escludere DispatcherServletAutoConfiguration dalle autoconfigurations chiamati, perché sarà registrare un DispatcherServlet a / e sovrascrivere la vostra

EDIT Nonostante il mio commento qui sotto dicendo che potrebbe non essere necessario questo, a meno che non avete bisogno dei vostri API in esecuzione su separata porte (e non suona come te), Dave Syer, uno degli autori di Spring Boot, ha risposto a una domanda molto simile qui: Configure multiple servletcontainers/servlets with spring boot

+0

Puoi fornire un esempio che includa i contesti ApiOne/Two.class? Inoltre, dove dovrei posizionare ServletRegistrationBean, nel contesto genitore dove attualmente sono registrati i miei Servizi? – Jan

+0

Mentre leggo la tua domanda, non sono sicuro che tu abbia bisogno di più DispatcherServlet. Qual è il ragionamento dietro a questo? Puoi facilmente avere due Api 'Controller che vivono in armonia l'uno con l'altro. Puoi semplicemente aggiungere '@RequestMapping ("/one ")' alla classe ApiOne e '@RequestMapping ("/two ")' alla classe ApiTwo. –

+0

Hanno gestori di errori in conflitto e configurazioni di convertitore di messaggi. Preferirei separarli gli uni dagli altri come ho fatto in un progetto basato su web.xml anni fa. – Jan

Problemi correlati