3

我们目前有一个 Spring Web 应用程序,并且正在使用 XML 文件进行配置。我们正在启动 Spring DispatcherServlet,它创建一个 XmlWebApplicationContext 并从默认位置加载它:spring-servlet.xml。

我正在使用上下文参数 contextConfigLocation 指定几个额外的配置文件。这会从 XML 文件加载我们的整个应用程序。

所以这就是我想要做的。XML 文件包含数据库连接信息和我们用于访问这些表的 DAO。我想使用其中一个 DAO 从数据库中读取一个值并从 XML 文件加载一组额外的 bean。

所以如果检索到的数据库值是橙色的,我想从 orange.xml 加载 bean。如果是苹果,我想加载apple.xml。我希望这些 bean 成为同一应用程序上下文的一部分,因此在加载它们之后,我可以继续前进而不会注意到差异。

我想知道我是否应该实现我自己的 XmlWebApplicationContext 子类并让 DispatcherServlet 实现它,但我不太确定如何继续。

4

3 回答 3

6

不完全从不同的文件加载,但您可以尝试使用 Spring Environment 和 Profile 抽象。

<beans profile="apple">
    <bean id="someBean">
       ...first set of bean parameters...
    </bean>
</beans>
<beans profile="orange">
    <bean id="someBean">
       ...second set of bean parameters...
    </bean>
</beans>

在java中:

context.getEnvironment().setActiveProfiles("orange");
context.refresh();
于 2013-05-17T13:02:41.063 回答
1

您可以使用 aBeanFactoryPostProcessor来加载配置。

例如,如果您有一个 LocationService,它将配置位置作为 String[]:

public class XmlBeanDefinitionReaderPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) beanFactory);
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        reader.setResourceLoader(new DefaultResourceLoader());
        reader.setEntityResolver(new ResourceEntityResolver(resourceLoader));
        reader.setEnvironment(new StandardEnvironment());
        LocationService locationService = (LocationService) beanFactory.getBean("locationService");

        reader.loadBeanDefinitions(locationService.getLocations());     
    }

}

不完全一样,因为读者不知道已经加载的 bean 并且可能是别名或 bean 名称 colisions。

请注意,您LocationService不应使用Autorwire,AOP Transactional Proxies和通常暗示使用BeanPostProcessors.

其他重用相同的选项XmlBeanDefinitionReader是覆盖postProcessBeanFactory方法XmlWebApplicationContext

public class CustomWebApplicationContext extends XmlWebApplicationContext  {

    private XmlBeanDefinitionReader reader;

    @Override
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        this.reader = reader;
        super.loadBeanDefinitions(reader);
    }

    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        LocationService locationService = (LocationService) beanFactory.getBean("locationService");
        this.reader.loadBeanDefinitions(locationService.getLocations());

        super.postProcessBeanFactory(beanFactory);
    }

}
于 2013-05-17T16:18:44.847 回答
0

我们最终扩展了 XmlWebApplicationContext 并覆盖了 loadBeans 方法。我们加载 bean,查找提供我们配置的 bean,然后切换配置文件并使用新配置文件再次运行。

感谢所有的帮助。

于 2013-05-20T17:22:03.890 回答