У меня есть некоторый опыт работы с Spring, а также есть несколько веб-приложений с чистой конфигурацией Java. Однако они обычно основаны на тихой простой настройке:
- конфигурация приложения для сервисов/репозиториев
- конфигурация диспетчера для одного диспетчера (и некоторых контроллеров)
- (опционально) пружинная защита для обеспечения доступа
Для моего текущего проекта мне нужно иметь отдельные контексты диспетчера с различной конфигурацией. Это не проблема с конфигурацией на основе XML, поскольку у нас есть выделенный ContextLoaderListener, который не зависит от конфигурации Dispatcher. Но с конфигурацией Java я не уверен, что то, что я делаю, пока в порядке;)
Вот общий 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";
}
}
Как уже было сказано, мне нужен второй (третий,...) диспетчер с другим отображением (и преобразователями представлений). Итак, я скопировал конфигурацию и добавил для обоих getServletName() (иначе оба будут названы «диспетчером», что вызовет ошибки). Второй конфиг выглядел так:
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";
}
}
Когда я использую это так, запуск приложения приводит к проблеме с ContextLoaderListener:
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)
...
Поэтому я удалил второй возврат MyAppConfig.class из одного из AbstractAnnotationConfigDispatcherServletInitializer, и он работает нормально. Однако это не кажется правильным;)
Насколько я понимаю: следует ли обрабатывать все DispatcherConfig в рамках одного AbstractAnnotationConfigDispatcherServletInitializer или их следует разделить, как я сделал? Я пытался настроить их в одном классе, но тогда моя конфигурация была полностью смешанной (поэтому я считаю, что это не желательный способ).
Как реализовать такой случай? Можно ли установить ContextLoaderListener в конфигурации java вне AbstractAnnotationConfigDispatcherServletInitializer? Или мне следует создать DefaultServlet, который имеет только корневую конфигурацию? Как насчет реализации базового интерфейса этой конфигурации WebApplicationInitializer?