根据数据库值动态加载spring xml文件

时间:2013-05-17 12:42:53

标签: java spring java-ee

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

我使用context-param contextConfigLocation指定了几个其他配置文件。这会从XML文件中加载整个应用程序。

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

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

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

3 个答案:

答案 0 :(得分:5)

不完全从不同的文件加载,但您可以尝试使用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();

答案 1 :(得分:1)

您可以使用BeanFactoryPostProcessor加载配置。

例如,如果您有一个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不应使用AutorwireAOP 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);
    }

}

答案 2 :(得分:0)

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

感谢您的帮助。