Fondamentalement, je veux diviser mon application en 2 parties. Chaque partie a ses propres éléments de sécurité et son propre @Controller
s. Le @Services
devrait être accessible depuis les deux parties.
J'ai donc pensé que je devrais obtenir 2 DispatcherServlet
. On écoute /admin/*
et le second écoutant tout le reste (/
). Chacun de ceux-ci aura son propre AnnotationConfigWebApplicationContext
afin que je puisse avoir un scan séparé des composants pour le @Controller
s.
Et parce que Spring Boot fournit une DispatcherServlet
écoute sur /
sorti de la boîte, je pensais, je peux juste ajouter un deuxième:
@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;
}
}
Le MyConfig2
classe, a seulement @Configuration
et @ComponentScan
. Dans le même package est un @Controller
.
Lors du démarrage de l'application, je peux voir que le deuxième mappage de servlet est enregistré, mais le @Controller
n'est pas. De plus, je peux maintenant accéder à tous@Controllers
de /
et/admin
.
Une idée de comment je peux faire fonctionner ça?
Je l'ai fait fonctionner d'une manière ou d'une autre!
Voici ma disposition de paquet:
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
n'empêche pas Spring Boot de créer son propre DispatcherServlet
avec le mappage /
. Vous pouvez supprimer cette ligne, si vous souhaitez ce mappage ou définir le vôtre.servletRegistrationBean.setLoadOnStartup(1)
si vous souhaitez que vos servlets soient initialisés au démarrage de l'application. Sinon, il attendra la première demande pour ce servlet.servletRegistrationBean.setName(...)
, sinon les servlets se remplaceront mutuellement.FooConfig.Java & BarConfig.Java:
@Configuration @ComponentScan @EnableWebMvc
public class FooConfig { }
@EnableWebMvc
Active l'analyse des composants. Sans lui, il ne trouvera pas la classe @Controller
.Le code du contrôleur et du service n'est pas important. Vous devez juste savoir que si vous avez @RequestMapping("/foo")
à l'intérieur FooController
, la demande doit être GET /foo/foo
Car le mappage d'URL du Servlet est /foo/*
. Il n'est pas possible d'appeler l'URL GET /foo
Car le mappage d'URL de servlet a besoin d'un /
À la fin de son chemin (en d'autres termes: GET /foo
Recherchera un servlet avec /
Mappage!), Bien que @RequestMapping("")
doive être appelée via GET /foo/
. Et bien sûr, il n'était pas possible d'utiliser /foo
Ou /foo*
Comme mappage de servlet (ou je n'ai tout simplement pas trouvé les paramètres appropriés pour cela)
Portée: Les contrôleurs ne peuvent pas se voir , bien qu'il soit pas possible de @Autowired
Les uns dans les autres. Le service ne peut pas non plus @Autowired
Aucun des contrôleurs. Mais les contrôleurs peuvent @Autowired
Le service.
Bien qu'il s'agisse d'une hiérarchie de contexte parent-enfant classique.
La seule "mauvaise" chose est que nous avons besoin de @EnableMvcConfig
Et que nous n'obtenons pas le sucre configuré automatiquement depuis Spring Boot dans le contexte. Le contexte parent est configuré automatiquement. J'ai mis des trucs de base de données dans le application.properties
Et j'ai fait une requête dans MyService
qui a été appelée par FooController
et ça a fonctionné parfaitement! :)
J'espère que cela peut aider certaines personnes!