Spring的项目配置
1. 配置必须是环境特定的
配置必须是特定于环境的——这只是生活中的一个事实。如果不是这种情况,那么它就不是配置,我们只会在代码中硬编码值。 对于 Spring 应用程序,您可以使用多种解决方案——从简单的解决方案一直到超级灵活、高度复杂的替代方案。
一种更常见和直接的解决方案是灵活使用属性文件和Spring 提供的一流属性支持 。 作为概念证明,为了本文的目的,我们将看一下一种特定类型的属性——数据库配置。将一种类型的数据库配置用于生产,另一种用于测试,另一种用于开发环境是非常有意义的。
2.每个环境的*.properties*文件
让我们开始我们的概念验证——通过定义我们想要定位的环境:
- Dev
- Staging
- Production
接下来 – 让我们创建 3 个属性文件 – 每个环境一个:
- persistence-dev.properties
- persistence-staging.properties
- persistence-production.properties
在典型的 Maven 应用程序中,这些可以驻留在src/main/resources中,但无论它们在哪里,在部署应用程序时它们都需要在类路径上可用。 一个重要的建议——将所有属性文件置于版本控制之下可以使配置更加透明和可重现。这与将配置放在磁盘上的某个地方并简单地将 Spring 指向它们是相反的。
3. Spring配置
在 Spring 中,我们将根据环境包含正确的文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:property-placeholder
location="
classpath*:*persistence-${envTarget}.properties" />
</beans>
当然也可以用 Java 配置来做同样的事情:
@PropertySource({ "classpath:persistence-${envTarget:dev}.properties" })
这种方法允许为特定的、集中的目的灵活地拥有多个*.properties*文件。例如——在我们的例子中,持久性 Spring 配置导入了持久性属性——这非常有意义。安全配置将导入与安全相关的属性等。
4. 在每个环境中设置属性
最终的可部署 war将包含所有属性文件—— persistence-*.properties的三个属性文件。由于这些文件的名称实际上不同,因此不必担心不小心包含了错误的文件。我们将设置** envTarget变量,从而从多个文件中**选择我们想要的实例。
envTarget变量可以在操作系统/环境中设置或作为 JVM 命令行的参数:
-DenvTarget=dev
5. 测试和 Maven
对于需要启用持久性的集成测试——我们只需在 pom.xml 中设置envTarget属性:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<envTarget>h2_test</envTarget>
</systemPropertyVariables>
</configuration>
</plugin>
相应的persistence-h2_test.properties文件可以放在src/test/resources中,这样它只会用于测试,不会在运行时不必要地包含和部署 war。
6. 更进一步
如果需要,可以通过多种方法为该解决方案构建额外的灵活性。 一种这样的方法是对属性文件的名称使用更复杂的编码,不仅指定使用它们的环境,还指定更多信息(例如持久性提供程序)。例如,我们可能会使用以下类型的属性:persistence-h2.properties、persistence-mysql.properties或更具体的:persistence-dev_h2.properties、persistence-staging_mysql.properties、persistence-production_amazonRDS.properties。
这种命名约定的优点——它只是一个约定,因为整体方法没有任何变化——就是透明。现在仅通过查看名称就可以更清楚地了解配置的作用:
- ** persistence-dev_h2.properties **:dev环境的持久化提供者是一个轻量级的内存 H2 数据库
- ** persistence-staging_mysql.properties ** :staging环境的持久性提供程序是一个 MySQL 实例
- ** persistence-production_amazon_rds.propertie ** :production环境的持久性提供者是 Amazon RDS