Project Configuration with Spring – 用Spring配置项目

最后修改: 2014年 6月 14日

中文/混合/英文(键盘快捷键:t)

Table of Contents

目录

1. Configuration Must Be Environment Specific

1.配置必须是特定环境的

Configuration must be environment specific – that’s just a fact of life. If that weren’t the case, then it wouldn’t be configuration and we would just hardcode values in code.

配置必须是针对环境的–这只是生活中的一个事实。如果不是这样的话,那就不是配置了,我们只是在代码中硬编码数值。

For a Spring application there are several solutions you can use – from simple solutions all the way to uber-flexible, highly complex alternatives.

对于一个Spring应用程序,你可以使用几种解决方案–从简单的解决方案一直到超灵活、高度复杂的替代品。

One of more common and straightforward solutions is a flexible use of properties files and the first class property support provided by Spring.

比较常见和直接的解决方案之一是灵活使用属性文件和Spring提供的第一类属性支持

As a proof of concept, for the purposes of this article, we’ll take a look at one specific type of property – the database configuration. It makes perfect sense to use one type of database configuration for production, another for testing and yet another for a dev environment.

作为一个概念的证明,为了这篇文章的目的,我们将看一下一个特定类型的属性–数据库配置。在生产环境中使用一种数据库配置,在测试环境中使用另一种,在开发环境中使用另一种,都是非常合理的。

2. The .properties Files for Each Environment

2.每个环境的.properties文件

Let’s start our Proof of Concept – by defining the environments we want to target:

让我们开始我们的概念证明–通过定义我们想要的目标环境。

    • Dev
    • Staging
    • Production

720

720

Next – let’s create 3 properties files – one for each of these environments:

接下来–让我们创建3个属性文件–每个环境都有一个。

  • persistence-dev.properties
  • persistence-staging.properties
  • persistence-production.properties

In a typical Maven application, these can reside in src/main/resources, but the wherever they are, they will need to be available on the classpath when the application is deployed.

在一个典型的Maven应用中,这些资源可以存放在src/main/resources中,但无论它们在哪里,当应用部署时,它们都需要在classpath上可用。

An important sidenote – having all properties files under version control makes configuration much more transparent and reproducible. This is in opposition to having the configs on disk somewhere and simply pointing Spring to them.

一个重要的附注–将所有属性文件置于版本控制之下,使得配置更加透明和可重复。这与将配置放在磁盘上的某个地方并简单地将Spring指向它们是相反的。

3. The Spring Configuration

3.Spring配置

In Spring, we’ll include the correct file based on the environment:

在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>

The same can of course be done with Java configuration as well:

当然,同样的情况也可以用Java配置来完成。

@PropertySource({ "classpath:persistence-${envTarget:dev}.properties" })

This approach allows for the flexibility of having multiple *.properties files for specific, focused purposes. For example – in our case, the persistence Spring config imports the persistence properties – which makes perfect sense. The security config would import security related properties and so on.

这种方法允许灵活地拥有多个*.properties文件,用于特定的、集中的目的。例如–在我们的案例中,持久化的Spring配置导入了持久化属性–这很有意义。安全配置将导入安全相关的属性,以此类推。

4. Setting the Property in Each Environment

4.在每个环境中设置属性

The final, deployable war will contain all properties files – for persistence, the three variants of persistence-*.properties. Since the files are actually named differently, there is no fear of accidentally including the wrong one. We will set the envTarget variable and thus select the instance we want from the multiple existing variants.

最后,可部署的战争将包含所有的属性文件–对于持久化,persistence-*.properties的三种变体。由于这些文件实际上是以不同的方式命名的,所以不用担心不小心包含了错误的文件。我们将设置envTarget变量,从而从现有的多个变体中选择我们想要的实例。

The envTarget variable can be set in the OS/environment or as a parameter to the JVM command line:

envTarget变量可以在操作系统/环境中设置,或者作为JVM命令行的参数。

-DenvTarget=dev

5. Testing and Maven

5.测试和Maven

For integration tests that need persistence enabled – we’ll simply set the envTarget property in the pom.xml:

对于需要启用持久性的集成测试–我们将简单地在pom.xml中设置envTarget属性。

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <configuration>
      <systemPropertyVariables>
         <envTarget>h2_test</envTarget>
      </systemPropertyVariables>
   </configuration>
</plugin>

The corresponding persistence-h2_test.properties file can be placed in src/test/resources so that it will only be used for testing and not unnecessarily included and deployed with the war at runtime.

相应的persistence-h2_test.properties文件可以放在src/test/resources中,这样它将只用于测试,而不是在运行时不必要地包含和部署在战争中。

6. Going Further

6.进一步发展

There are several ways to build additional flexibility into this solution if needed.

如果需要,有几种方法可以在这个解决方案中建立额外的灵活性。

One such way is to use a more complex encoding for the names of the properties files, specifying not just the environment in which they are to be used, but also more information (such as the persistence provider). For example, we might use the following types of properties: persistence-h2.properties, persistence-mysql.properties or, even more specific: persistence-dev_h2.properties, persistence-staging_mysql.properties, persistence-production_amazonRDS.properties.

其中一个方法是对属性文件的名称使用更复杂的编码,不仅指定它们的使用环境,而且还指定更多的信息(如持久化提供者)。例如,我们可以使用以下类型的属性。persistence-h2.properties, persistence-mysql.properties 或者,更具体的。persistence-dev_h2.properties, persistence-staging_mysql.properties, persistence-production_amazonRDS.properties

The advantage of such a naming convention – and it is just a convention as nothing changes in the overall approach – is simply transparency. It now becomes much clearer what the configuration does only by looking at the names:

这种命名惯例的好处–而且它只是一种惯例,因为在整个方法上没有任何变化–只是透明。现在只需看一下名字,就能更清楚地了解配置的作用。

  • persistence-dev_h2.properties: the persistence provider for the dev environment is a lightweight, in-memory H2 database
  • persistence-staging_mysql.properties: the persistence provider for the staging environment is a MySQL instance
  • persistence-production_amazon_rds.propertie: the persistence provider for the production environment is Amazon RDS

7. Conclusion

7.结论

This article discusses a flexible solution for doing environment specific configuration in Spring. An alternative solution using profiles can be found here.

这篇文章讨论了在Spring中进行环境特定配置的灵活解决方案。使用配置文件的替代解决方案可以在这里找到

The implementation of the solution can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

解决方案的实现可以在GitHub项目中找到–这是一个基于Maven的项目,所以应该很容易导入并按原样运行。