带有多个DispatcherServlet的Spring Boot,每个都有自己的@Controllers

时间:2015-06-05 15:26:37

标签: spring spring-mvc servlets spring-boot spring-4

基本上我想将我的应用程序分成两部分。每个部分都有自己的安全性和自己的@Controller。应该可以从这两个部分访问@Services

所以我想,我应该得到2 DispatcherServlet。一个人听/admin/*,另一个人听其他一切(/)。其中每个都有自己的AnnotationConfigWebApplicationContext,因此我可以对@Controller进行单独的组件扫描。

因为Spring Boot提供了一个DispatcherServlet开箱即用的/,我想,我可以添加第二个:

@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;
    }
}

MyConfig2班级只有@Configuration@ComponentScan。在同一个包中是@Controller

启动应用程序时,我可以看到第二个servlet映射已注册,但@Controller未注册。此外,我现在可以从@Controllers /访问所有 /admin

知道如何让这个工作吗?

1 个答案:

答案 0 :(得分:34)

我以某种方式工作了!

这是我的套餐布局:

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

<强> Application.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;
    }
}
  • exclude确实阻止Spring Boot使用DispatcherServlet映射创建自己的/。如果您想要该映射或定义自己的映射,则可以删除该行。
  • 如果要在应用程序启动时初始化Servlet,可以添加servletRegistrationBean.setLoadOnStartup(1)。否则它将等待该servlet的第一个请求。
  • 设置servletRegistrationBean.setName(...)很重要,否则servlet会互相覆盖。

FooConfig.java&amp; BarConfig.java:

@Configuration @ComponentScan @EnableWebMvc
public class FooConfig { }
  • @EnableWebMvc将启用组件扫描。没有它,它就找不到@Controller类。

控制器和服务代码并不重要。您只需要知道,如果您@RequestMapping("/foo")FooController,则请求必须为GET /foo/foo,因为Servlet的URL映射为/foo/*。无法调用URL GET /foo,因为Servlet URL映射在其路径末尾需要/(换句话说:GET /foo将查找具有该值的Servlet /映射!),但必须通过@RequestMapping("")调用GET /foo/。当然,无法使用/foo/foo*作为Servlet映射(或者我只是找不到正确的设置)

范围:控制器无法看到,但 <{>} <{1}他们在彼此。此外,服务还可以@Autowired任何控制器。 控制器可以@Autowired服务。

虽然它是一个经典的父子上下文层次结构。

唯一的&#34;坏&#34;问题是,我们需要@Autowired并且不能在上下文中从Spring启动获取自动配置的糖。父上下文正在自动配置。我在@EnableMvcConfig中添加了一些数据库内容,并在application.properties内进行了查询,该查询由MyService调用,并且运行完美! FooController

我希望这可以帮助一些人!