Spring 使用多个 DispatcherServlet 启动,每个 DispatcherServlet 都有自己的 @Controllers
Spring Boot with multiple DispatcherServlet, each having their own @Controllers
基本上我想将我的应用程序分成两部分。每个部分都有自己的安全内容和自己的 @Controller
s。 @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
class,只有@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 引导创建自己的 DispatcherServlet
和 /
映射。如果您想要该映射或定义您自己的映射,您可以删除该行。
- 如果您希望在应用程序启动时初始化您的 Servlet,您可以添加
servletRegistrationBean.setLoadOnStartup(1)
。否则它将等待对该 servlet 的第一个请求。
- 设置
servletRegistrationBean.setName(...)
很重要,否则 servlet 将相互覆盖。
FooConfig.java & BarConfig.java:
@Configuration @ComponentScan @EnableWebMvc
public class FooConfig { }
@EnableWebMvc
将启用组件扫描。没有它,它将找不到 @Controller
class.
控制器和服务代码不重要。您只需要知道,如果 FooController
中有 @RequestMapping("/foo")
,则请求必须是 GET /foo/foo
,因为 Servlet 的 URL 映射是 /foo/*
。调用 URL GET /foo
是不可能的,因为 Servlet URL 映射在其路径末尾需要一个 /
(换句话说:GET /foo
将看起来对于具有 /
映射的 Servlet!),尽管必须通过 GET /foo/
调用 @RequestMapping("")
。当然,不可能使用 /foo
或 /foo*
作为 Servlet 映射(或者我只是没有找到正确的设置)
范围: 控制器不能看到彼此,尽管不可能 @Autowired
他们彼此。此外,服务不能 @Autowired
任何控制器。 但是控制器可以@Autowired
服务。
尽管它是一个 class真正的父子上下文层次结构。
唯一 "bad" 的事情是,我们需要 @EnableMvcConfig
而不是从上下文中的 Spring 引导获取自动配置的糖。父上下文正在自动配置。我在 application.properties
中放置了一些数据库内容,并在 MyService
中进行了查询,该查询被 FooController
调用并且运行完美! :)
希望这对某些人有所帮助!
基本上我想将我的应用程序分成两部分。每个部分都有自己的安全内容和自己的 @Controller
s。 @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
class,只有@Configuration
和@ComponentScan
。在同一个包中是 @Controller
.
启动应用程序时,我可以看到,第二个 servlet 映射正在注册,但 @Controller
没有。此外,我现在可以从 /
和 /admin
.
@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 引导创建自己的DispatcherServlet
和/
映射。如果您想要该映射或定义您自己的映射,您可以删除该行。- 如果您希望在应用程序启动时初始化您的 Servlet,您可以添加
servletRegistrationBean.setLoadOnStartup(1)
。否则它将等待对该 servlet 的第一个请求。 - 设置
servletRegistrationBean.setName(...)
很重要,否则 servlet 将相互覆盖。
FooConfig.java & BarConfig.java:
@Configuration @ComponentScan @EnableWebMvc
public class FooConfig { }
@EnableWebMvc
将启用组件扫描。没有它,它将找不到@Controller
class.
控制器和服务代码不重要。您只需要知道,如果 FooController
中有 @RequestMapping("/foo")
,则请求必须是 GET /foo/foo
,因为 Servlet 的 URL 映射是 /foo/*
。调用 URL GET /foo
是不可能的,因为 Servlet URL 映射在其路径末尾需要一个 /
(换句话说:GET /foo
将看起来对于具有 /
映射的 Servlet!),尽管必须通过 GET /foo/
调用 @RequestMapping("")
。当然,不可能使用 /foo
或 /foo*
作为 Servlet 映射(或者我只是没有找到正确的设置)
范围: 控制器不能看到彼此,尽管不可能 @Autowired
他们彼此。此外,服务不能 @Autowired
任何控制器。 但是控制器可以@Autowired
服务。
尽管它是一个 class真正的父子上下文层次结构。
唯一 "bad" 的事情是,我们需要 @EnableMvcConfig
而不是从上下文中的 Spring 引导获取自动配置的糖。父上下文正在自动配置。我在 application.properties
中放置了一些数据库内容,并在 MyService
中进行了查询,该查询被 FooController
调用并且运行完美! :)
希望这对某些人有所帮助!