如何从WEB-INF加载“迷你” spring上下文以初始化实际的应用程序上下文

时间:2019-05-03 08:25:03

标签: java spring spring-mvc applicationcontext

我有一个旧版Spring 3 Web应用程序,该应用程序使用配置数据库来加载url,超时等配置值。

当前,config-db中的值以编程方式使用。

当前存在一个应用程序上下文,并且配置数据库访问器代码以及所有其他组件都已初始化(Spring存储库)。

由于存在单个上下文,因此无法在'@Value'批注中使用config-database中的配置值。在我可以访问这些值时,上下文已初始化,bean已创建。

目标是允许通过Bean中的“ @Value”注释使用基于config-db的值。

所以我的想法是将config-db访问器bean(数据源,实体管理器等)分离到一个'mini'上下文中,并且:

  1. 从一开始就加载该小型上下文,
  2. 然后将config-db中的值加载到Properties
  3. ,然后将该属性插入“真实”上下文的PropertySources中。

我几乎成功完成了所有工作,但是我只能从类路径而不是从WEB-INF(WEB-INF不在类路径上,只有WEB-INF /类在)上初始化此“迷你上下文”。我当前的初始化看起来像这样:

Spring调度程序servlet的上下文侦听器注册:

<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. 我不能在带有'location =“ / WEB-INF / ....”'的迷你上下文中使用property-placeholders或util:properties。

我尝试使用GenericXmlApplicationContext并使用它的setResourceLoader,但还没有成功。

有没有办法从WEB-INF而不是从类路径以编程方式加载spring context.xml?

1 个答案:

答案 0 :(得分:0)

在Spring Web应用程序中,可以通过org.springframework.web.context.support.ServletContextResourceLoader访问WEB-INF的内容。该类可以从WEB-INF加载资源。

因此initialize方法应如下所示:

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();
}