spring spring-mvc servlets spring-boot spring-4

Spring Boot con mĂșltiples DispatcherServlet, cada uno con sus propios @Controllers



spring-mvc servlets (1)

¡Lo tengo funcionando de alguna manera!

Aquí está mi diseño del paquete:

test.foo. FooConfig.java FooController.java test.bar. BarConfig.java BarController.java test.app. Application.java MyService.java src/main/resources/application.properties

Aplicación.java:

@SpringBootApplication(exclude=DispatcherServletAutoConfiguration.class) public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } @Bean public ServletRegistrationBean foo() { DispatcherServlet dispatcherServlet = new DispatcherServlet(); AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(FooConfig.class); dispatcherServlet.setApplicationContext(applicationContext); ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/foo/*"); servletRegistrationBean.setName("foo"); return servletRegistrationBean; } @Bean public ServletRegistrationBean bar() { DispatcherServlet dispatcherServlet = new DispatcherServlet(); AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(BarConfig.class); dispatcherServlet.setApplicationContext(applicationContext); ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/bar/*"); servletRegistrationBean.setName("bar"); return servletRegistrationBean; } }

  • La exclude impide que Spring Boot cree su propio DispatcherServlet con / mapping. Puede eliminar esa línea, si desea que la asignación o definir su propia.
  • Puede agregar servletRegistrationBean.setLoadOnStartup(1) si desea que sus Servlets se inicialicen al iniciar la aplicación. De lo contrario, esperará la primera solicitud de ese servlet.
  • Es importante establecer servletRegistrationBean.setName(...) , de lo contrario, los servlets se anularán entre sí.

FooConfig.java & BarConfig.java:

@Configuration @ComponentScan @EnableWebMvc public class FooConfig { }

  • @EnableWebMvc habilitará la exploración de componentes. Sin él, no encontrará la clase @Controller .

El código de Controlador y Servicio no es importante. Solo debes saber que si tienes @RequestMapping("/foo") dentro de FooController , la solicitud debe ser GET /foo/foo porque la asignación de URL del Servlet es /foo/* . No es posible llamar a la URL GET /foo porque la asignación de la URL del Servlet necesita un / al final de su ruta (en otras palabras: GET /foo buscará un Servlet con / mapping), aunque @RequestMapping("") debe ser llamado a través de GET /foo/ . Y, por supuesto, no fue posible usar /foo o /foo* como asignación de Servlet (o simplemente no encontré la configuración correcta para eso)

Ámbito: los controladores no pueden verse entre sí, aunque no es posible que @Autowired los haya @Autowired . Además, el Servicio no puede @Autowired ninguno de los Controladores. Pero los Controladores pueden @Autowired el Servicio.

Aunque es una jerarquía de contexto padre-hijo clásica.

Lo único "malo" es que necesitamos @EnableMvcConfig y no obtenemos el azúcar configurado automáticamente desde Spring boot dentro del contexto. El contexto padre se está configurando automáticamente. Puse algunas cosas de la base de datos dentro de application.properties e hice una consulta dentro de MyService que MyService llamó y ¡funcionó a la perfección! :)

Espero que esto pueda ayudar a algunas personas!

Básicamente quiero dividir mi aplicación en 2 partes. Cada parte tiene su propio material de seguridad y el propio @Controller s. Los @Services deben ser accesibles desde ambas partes.

Así que pensé, debería obtener 2 DispatcherServlet . Uno escucha /admin/* y el segundo escucha todo lo demás ( / ). Cada uno de ellos tendrá su propio AnnotationConfigWebApplicationContext para que pueda tener una exploración de componentes separada para los @Controller s.

Y como Spring Boot proporciona un DispatcherServlet escucha dentro / fuera de la caja, pensé, solo puedo agregar una segunda:

@Configuration public class MyConfig { @Bean(name="myDS") public DispatcherServlet myDS(ApplicationContext applicationContext) { AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext(); webContext.setParent(applicationContext); webContext.register(MyConfig2.class); // webContext.refresh(); return new DispatcherServlet(webContext); } @Bean public ServletRegistrationBean mySRB(@Qualifier("myDS") DispatcherServlet dispatcherServlet) { ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet); servletRegistrationBean.addUrlMappings("/admin/*"); servletRegistrationBean.setName("adminServlet"); return servletRegistrationBean; } }

La clase MyConfig2 , solo tiene @Configuration y @ComponentScan . Dentro del mismo paquete hay un @Controller .

Al iniciar la aplicación, puedo ver que se está registrando el segundo mapeo de servlet, pero no el @Controller . Además, ahora puedo acceder a todos los @Controllers desde / y /admin .

¿Alguna idea de cómo puedo hacer que esto funcione?