Мне нужно изменить web.xml в моем проекте после проверки некоторых параметров. Мой параметр contextConfigLocation в web.xml выглядит следующим образом:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:*/test-spring-config.xml classpath:*/someContext.xml classpath:applicationContext.xml classpath:databaseContext.xml</param-value>
</context-param>
Теперь мне нужно добавить classpath: securityContext.xml в свой контекстConfigLocation в web.xml при проверке некоторого состояния до того, как мое приложение будет загружено в tomcat. Я попытался сделать это в своем классе applicationInitializer, который реализует ServletContextListener следующим образом (часть кода показана):
public class ApplicationInitializer implements ServletContextListener
{
public void contextInitialized(ServletContextEvent event)
{ ServletContext sc = event.getServletContext();
if(someConditionIsTrue){
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("classpath:securityContext.xml");
appContext.setServletContext(sc);
appContext.refresh();
sc.setAttribute("org.springframework.web.context.WebApplicationContext.ROOT",appContext);
}
Но это не работает, потому что я снова загружаю контекст в свой web.xml как
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Может кто-нибудь предложить, как справиться с этой проблемой? Любые предложения приветствуются.
ApplicationInitializer должен расширять ContextLoaderListener для вашего сценария, а класс слушателя должен указывать на ApplicationInitializer в web.xml
После нескольких дней борьбы я смог сделать это, создав класс CustomContextLoaderListener, который расширяет ContextLoaderListener и переопределяет его метод createContextLoader, который теперь возвращает customContextLoader следующим образом:
@Override
protected ContextLoader createContextLoader(){
return new CustomContextLoader();
}
Класс CustomContextLoader расширяет ContextLoader, и я переопределяю его метод customizeContext следующим образом:
@Override
protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext){
super.customizeContext(servletContext, applicationContext);
String[] oldLocations = applicationContext.getConfigLocations();
String[] newLocations;
if(conditionIsTrue){
newLocations = new String[oldLocations.length+1];
for (int i = 0; i < oldLocations.length; i++) {
newLocations[i] = oldLocations[i];
}
newLocations[oldLocations.length] ="classpath:securityContext.xml";
}else{
newLocations = new String[oldLocations.length];
newLocations = Arrays.copyOf(oldLocations, oldLocations.length);
}
applicationContext.setConfigLocations(newLocations);
}
Не забудьте добавить класс customContextLoaderListener в ваш web.xml.
<listener>
<listener-class>com.abc.px.customContextLoaderListener</listener-class>
</listener>
Это оно! Таким образом, я могу условно установить свой контекст в web.xml. Надеюсь, это поможет кому-то!