具有多个 DispatcherServlet 的 Spring Boot,每个 DispatcherServlet 都有自己的 @Controller

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

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

所以我想,我应该得到 2 个 DispatcherServlet。一个监听 /admin/* ,第二个监听其他所有内容 ( / )。每一个都有自己的 AnnotationConfigWebApplicationContext 所以我可以对 @Controllers 进行单独的组件扫描。

而且由于 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 没有。此外,我现在可以从 / /admin 访问 all @Controllers


知道我怎样才能让它工作吗?

最佳答案

我让它以某种方式工作!

这是我的包装布局:

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 & BarConfig.java:

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

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

作用域: Controller 不能看到彼此,虽然@Autowired不可能在彼此。此外,服务不能 @Autowired 任何 Controller 。 但是 Controller 可以@Autowired服务。

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

唯一“坏”的事情是,我们需要 @EnableMvcConfig 并且不从上下文中的 Spring 引导中获取自动配置的糖。父上下文正在自动配置。我在 application.properties 中放入了一些数据库内容,并在 MyService 中进行了查询,该查询由 FooController 调用,并且运行良好! :)

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

关于具有多个 DispatcherServlet 的 Spring Boot,每个 DispatcherServlet 都有自己的 @Controller,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30670327/

相关文章:

apache - 删除 Content-Disposition 会导致 ClientAbortException : java.net.SocketException:套接字写入错误:连接被对等方中止

java - 使用 Spring 上下文配置文件的 Jersey 2.4 测试 - DI 不工作

java - JSP内容显示在浏览器上

Java : How to accommodate special characters in the filename while uploading and downloading the file?

spring - org.springframework.beans.factory.BeanCreationException : Error creating bean with name 'requestMappingHandlerMapping' defined

Java Servlet 命令行处理

java - jsp 未迭代 servlet 发送的 Linkedhashmap

java - 使用@EnableOAuth2Client 的 OAuth2 客户端手动配置不起作用

spring - 如何自定义 Grails Spring Security Core 2 登录/注销 Controller 和 View ?

java - Spring Websocket getServerName 服务中