Ich habe einige Erfahrung Spring jetzt und habe auch einige reine Java-Config-Web-Apps im Einsatz. Diese sind jedoch in der Regel auf einer ruhigen einfachen Aufbau basiert:Spring Java Config mit mehreren Dispatcher
- Anwendung Config für Dienste/Repositories
- Dispatcher Konfiguration für einen Dispatcher (und einigen Controllern)
- (optional) Feder Sicherheit den Zugang zu sichern
Für mein aktuelles Projekt brauche ich separate Dispatcher Kontexte mit unterschiedlicher Konfiguration. Das ist kein Problem mit der XML-basierten Konfiguration, da wir einen dedizierten ContextLoaderListener haben, der unabhängig von der Dispatcher-Konfiguration ist. Aber mit Java-Config bin ich nicht sicher, ob das, was ich tue, ist in Ordnung so weit,)
Hier ist eine gemeinsame DispatcherConfig:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new class[]{MyAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{MyDispatcherConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/mymapping/*"};
}
@Override
protected String getServletName() {
return "myservlet";
}
}
Wie gesagt, ich brauche eine zweite (dritte, ...) Dispatcher mit einem anderen Mapping (und View Resolver). Also habe ich die Konfiguration kopiert und für beide getServletName() hinzugefügt (andernfalls werden beide als "Dispatcher" bezeichnet, was zu Fehlern führen wird). Die zweite Konfiguration sah wie folgt aus:
public class AnotherWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new class[]{MyAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{AnotherDispatcherConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/another_mapping/*"};
}
@Override
protected String getServletName() {
return "anotherservlet";
}
}
Wenn ich es so, Anwendung führt zu einem Problem mit Context Start:
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:277)
...
So entfernte ich die zweite MyAppConfig.class Rückkehr aus einer der AbstractAnnotationConfigDispatcherServletInitializer und es funktioniert gut. Aber das Gefühl, dass nicht der richtige Weg zu sein;)
Für mein Verständnis: sollten alle DispatcherConfig innerhalb eines AbstractAnnotationConfigDispatcherServletInitializer behandelt werden oder sollte ich sie trennen, wie ich getan habe? Ich habe versucht, sie in einer Klasse zu konfigurieren, aber dann war meine Konfiguration völlig gemischt (also glaube ich, dass das nicht der gewünschte Weg ist).
Wie implementieren Sie einen solchen Fall? Ist es möglich, den ContextLoaderListener in Java-Konfiguration außerhalb der AbstractAnnotationConfigDispatcherServletInitializer? Oder sollte ich eine DefaultServlet erstellen, die nur die Root-Konfiguration hat? Was ist mit der Implementierung der Basisschnittstelle dieser Konfiguration WebApplicationInitializer?
Können Sie den Grund für den Bedarf mehrere Disponenten in einer einzigen Anwendung zu erklären? Der ganze Sinn von Front Controller ist, dass Sie Ihre Anfragen auf eins multiplexen. – chrylis
@chrylis: sicher. Das Projekt ähnelt eher einem Modul-basierten Baukasten für Shared Services. Diese sind nicht miteinander verknüpft, teilen sich jedoch die gleiche Basiskonfiguration und dieselben Entitäten. Zwei Anwendungen zu implementieren ist ein No-Go in diesem Projekt und versuchen, den Dispatcher zu konfigurieren, um alle Arten von View-Technologien (einige basieren auf Kacheln, andere auf Jsp, neueren auf Thymeleaf) ist auch eine schlechte Idee. – delimiter
Warum ist es eine schlechte Idee? Spring Boot macht es einfach. – chrylis