как загрузить «мини» контекст весны из WEB-INF, чтобы инициализировать реальный контекст приложения - PullRequest
0 голосов
/ 03 мая 2019

У меня есть устаревшее веб-приложение Spring 3, которое использует базу данных конфигурации для загрузки значений конфигурации, таких как URL-адреса, тайм-ауты и т. Д.

В настоящее время значения из config-db используются программно.

В настоящее время существует один контекст приложения, и в этом код доступа к базе данных конфигурации инициализируется (репозиторий Spring) вместе со всеми другими компонентами.

Из-за этого единственного контекста значения конфигурации из базы данных config нельзя использовать в аннотациях @Value. К тому времени, когда я могу получить доступ к значениям, контекст инициализируется, бины уже созданы.

Целью было бы разрешить использование значений config-db через аннотации @Value в bean-компонентах.

Таким образом, моя идея заключалась в том, чтобы разделить компоненты доступа config-db (источник данных, менеджер сущностей и т. Д.) В контекст 'mini' и:

  1. загрузить этот мини-контекст в самом начале,
  2. затем загрузите значения из config-db в Свойства
  3. и затем вставьте эти свойства в PropertySources «реального» контекста

Мне удалось почти все, но я могу инициализировать этот «мини-контекст» только из пути к классам, а не из WEB-INF (WEB-INF отсутствует в пути к классам, только WEB-INF / классы). Моя текущая инициализация выглядит так:

Регистрация прослушивателя контекста для сервлета диспетчера Spring:

<servlet>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextInitializerClasses</param-name>
        <param-value>xxx.xxx.ContextInitializer</param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/application-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Затем в ContextInitializer:

public void initialize(ConfigurableApplicationContext applicationContext) {
    ClassPathXmlApplicationContext miniContext = 
            new ClassPathXmlApplicationContext("jpa-context-for-config-db.xml");
    ParameterDao parameterDao = miniContext.getBean(ParameterDao.class);
    Properties propertiesFromConfigDb = getPropertiesFromConfigDb(parameterDao);
    applicationContext.getEnvironment().getPropertySources().addFirst(
            new PropertiesPropertySource("parameterDaoBasedProperties", propertiesFromConfigDb));
    miniContext.close();
}

Это работает, но

  1. Я должен поместить мини-контекстный XML в / WEB-INF / classes, который не там, где находятся другие контекстные файлы (другие контекстные файлы находятся в / WEB-INF)

  2. Я не могу использовать свойства-заполнители или util: свойства в мини-контексте с 'location = "/ WEB-INF / ...."'.

Я пытался использовать GenericXmlApplicationContext и поиграл с его setResourceLoader, но пока не получилось.

Так есть ли способ загрузить весенний context.xml программно из WEB-INF, а не из classpath?

1 Ответ

0 голосов
/ 24 мая 2019

В весеннем веб-приложении доступ к содержимому WEB-INF можно получить через org.springframework.web.context.support.ServletContextResourceLoader. Этот класс может загружать ресурсы из WEB-INF.

Таким образом, метод инициализации должен выглядеть следующим образом:

public void initialize(ConfigurableApplicationContext applicationContext) {
    ServletContext servletContext = ContextLoaderListener.getCurrentWebApplicationContext().getServletContext();
    GenericXmlApplicationContext miniContext = new GenericXmlApplicationContext();
    miniContext.setResourceLoader(new ServletContextResourceLoader(servletContext));
    miniContext.load("/WEB-INF/jpa-context-for-config-db.xml");
    miniContext.refresh();
    ParameterDao parameterDao = miniContext.getBean(ParameterDao.class);
    Properties propertiesFromConfigDb = getPropertiesFromConfigDb(parameterDao);
    applicationContext.getEnvironment().getPropertySources().addFirst(
            new PropertiesPropertySource("parameterDaoBasedProperties", propertiesFromConfigDb));
    miniContext.close();
}
...