我们目前有一个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实现它,但我不太清楚如何继续这样做。
答案 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
不应使用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);
}
}
答案 2 :(得分:0)
我们最终扩展了XmlWebApplicationContext并覆盖了loadBeans方法。我们加载bean,查找提供配置的bean,然后切换配置文件并使用新配置文件再次运行。
感谢您的帮助。