我正在尝试找到在Tomcat中运行的Spring webapp中传递复杂配置的最佳方法。目前,我使用JNDI将数据源和字符串从Tomcat上下文传递到webapp,这很有效。
但是,让我说我需要选择通知服务的实现。 Spring无法有条件地选择实例化哪个bean(尽管在过去我使用JNDI字符串通过设置contextConfigLocation来导入预定义的bean配置)。
我还看过许多提供配置工具的webapps,它将创建一个自定义WAR文件。在我看来,这是一种糟糕的形式,如果没有其他原因,它会阻止从上游重新部署WAR而不进行多次检查,以确保所有配置都已重新应用。
理想情况下,我可以在webapp之外提供存在于文件系统上的Spring XML文件。但是,spring import指令似乎没有解决$ {}变量,因此无法提供自定义。
我是否可以使用任何技术将复杂配置与webapp正确分开?
答案 0 :(得分:12)
如果我有一组特定的bean要配置,并且此配置必须与WAR文件分开,我通常会执行以下操作:
在 applicationContext.xml :
中<!-- here you have a configurer based on a *.properties file -->
<bean id="configurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file://${configDir}/configuration.properties"/>
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="searchSystemEnvironment" value="false" />
</bean>
<!-- this is how you can use configuration properties -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${smtp.host}"/>
</bean>
在 configuration.properties :
中smtp.host=smtp.your-isp.com
您还需要使用-DconfigDir = / path / to / configuration / directory
启动Tomcat答案 1 :(得分:3)
如果您使用的是Spring 3,则可以利用Spring Expression Language。比方说,你有两个应用程序app1.war和app2.war,他们需要一个属性文件名为config.properties。应用程序将使用上下文路径/ app1和/ app2进行部署。
在公共目录中创建两个目录app1和app2,例如。 C:\ myConfig \ app1和C:\ myConfig \ app2。
将app.properties放在app1中,将另一个config.properties放在app2中。
然后创建一个文件$ {CATALINA_HOME} / CONF / [引擎] / [主机名] /context.xml.default与内容:
context.xml.default:
<Context>
<Parameter name="myConfigDirectory" value="C:/myConfig" override="false"/>
</Context>
参数myConfigDirectory可供主机上的所有应用程序使用。这是更好地创造context.xml.default而不是在server.xml中这个参数,因为该文件可以在以后无需重新启动Tomcat的改变。
在战争内可以访问使用使用SpEL表达config.properties applicationContext.xml中: “#{contextParameters.myConfigDirectory + servletContext.contextPath} /config.properties”,因此,例如可以这样写:
的applicationContext.xml:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:#{contextParameters.myConfigDirectory + servletContext.contextPath}/config.properties" />
</bean>
在表达式将得到扩大到C:/的myconfig / APP1的应用的的contextPath / APP1,和C:/的myconfig / APP2的应用的的contextPath / APP2。这将使应用程序根据其contextPath访问config.properties文件。
答案 2 :(得分:0)
如果您希望在Web容器之间完全可移植,则不能依赖WAR文件之外的任何内容。在Tomcat中,SecurityManager允许您发现部署代码的磁盘上的物理位置,然后您可以使用该知识将磁盘导航到放置配置文件的位置。