30

我正在开发一个包含 4 个产品的产品套件。现在,所有的配置数据要么在 XML 文件中,要么在属性文件中。这种方法是不可维护的,因为我们必须为不同的环境(例如生产、开发等)管理不同的配置文件。

那么,处理配置数据的最佳方式是什么?

另外,我们可以把它模块化成一个单独的模块吗?让所有产品都可以使用这个模块。我们不想使用属性文件。我正在寻找一种解决方案,在该解决方案中,我们可以将所有配置特定代码作为新的配置模块移动,并将所有配置数据保存在数据库中。

4

7 回答 7

21

使用commons-configuration你有一个统一的 API 来访问属性,无论它们是如何表示的 - .properties、xml、JNDI 等。例如:

config.properties

jdbcHost=192.168.12.35
jdbcUsername=dbuser
jdbcPassword=pass

config.xml

<config>
   <jdbcHost>192.168.12.35</jdbcHost>
   <jdbcUsername>dbuser</jdbcUsername>
   <jdbcPassword>pass</jdbcPassword>
</config>

在这两种情况下,它们都可以通过以下方式访问:

String host = config.getString("jdbcHost");
于 2010-02-24T06:37:39.520 回答
12

你快到了......我会保持你的相同方法并为通过类似于以下任一方法运行的应用程序实例提取正确的配置文件:

  1. 以不同的方式命名您的所有配置文件,并让您的应用程序通过一些独特的标准(用户名、主机名等)将它们拉入:

    • 生产.properties
    • 开发者1 .properties
    • 开发人员2 .properties
  2. 将它们保存在代码库之外的位置,该位置基于应用程序假定存在的环境变量:

    • YOURAPP_CONFIG_DIR /server_config.xml
    • YOURAPP_CONFIG_DIR /database_config.properties

我什至在同一个项目中使用了这些方法的组合(#1 用于构建过程配置,#2 用于运行时配置)。

于 2010-02-24T06:37:58.460 回答
5

如果您的应用程序使用数据库,您可以创建一个“配置”表,如下所示:

create table configuration (mode char(3), key varchar(255), value varchar(1023));

您将使用初始化脚本对其进行初始化,例如 init.sql,其内容如下:

insert into configuration values ('pro', 'param1', 'value1'); -- production
insert into configuration values ('dev', 'param1', 'value1'); -- development
insert into configuration values ('tst', 'param1', 'value1'); -- testing
...

这种方法的好处如下:

  • 您将脚本与代码一起版本化
  • 您可以通过添加用户/组 ID 轻松扩展它以包含每个用户或每个组的设置
  • 如果需要,您可以在运行时更改设置
  • 您可以使用通常用于处理核心应用程序数据的相同堆栈(JPA + DAO、Cayenne...)来处理配置数据
于 2010-02-24T11:22:42.173 回答
4

对于我们所有的环境,配置数据以属性文件的形式存在于目标机器上。我们使用SpringFramework 中的PropertyPlaceholderconfigurer将这些属性绑定到我们的应用程序,以保持跨环境的可移植性。

例如,只要我知道 /etc/myapp/database.properties 将出现在我的应用程序将运行的任何机器上,那么在我的 spring 配置中,我只需要这样的东西:

    <bean id="myPropertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>/etc/myapp/database.properties</value>
        </list>
    </property>
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url"
        value="jdbc:mysql://${db.host}:3306/${db.name}" />
    <property name="username" value="${db.user}" />
    <property name="password" value="${db.pass}" />     
</bean>

该 Spring 类有很多关于属性文件可以存放在哪里的选项。您甚至可以对它们进行替换并将它们作为环境变量传递:

    <bean id="myPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="searchSystemEnvironment" value="true" />
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="locations">
        <list>
            <value>${database.configuration.file.url}</value>
        </list>
    </property>
</bean>

在 bash_profile (或其他)中: export JAVA_OPTS="-Ddatabase.configuration.file.url=file:///etc/myapp/database.properties"

或者当你调用“java”时传入相同的 -D 选项,这取决于你在做什么。

FWIW,我们将属性文件单独维护为 RPM。

于 2010-02-24T09:00:16.573 回答
2

有很多不同的策略。所有这些都很好,取决于最适合您的。

  1. 构建单个工件并将配置部署到单独的位置。工件可能有占位符变量,并且在部署时,可以读入配置。看看 Springs 属性占位符。它非常适用于使用 Spring 并且不涉及涉及操作的 webapps。
  2. 有一个位于 webapp 之外的外部属性配置。保持位置不变并始终从属性配置中读取。在任何阶段更新配置,重新启动将获得新值。
  3. 如果您正在修改环境(即正在使用的应用程序服务器或用户/组权限),请查看将上述方法与 puppet 或 chef 一起使用。还可以查看使用这些工具管理您的配置文件。
于 2012-04-24T01:31:29.660 回答
0

环境变量几乎是最简单的方法。像任何其他时间一样设置它们,使用/访问它们System.getenv("...")

于 2017-05-24T20:53:56.910 回答
0

Config是一个配置文件管理工具。您可以创建在所有环境中通用的配置,也可以创建特定于环境的配置。您可以继续使用您的 XML 和属性文件,并让 Config 维护环境的差异。您可以将 Config 视为您的集中式数据库,它可以以您想要的格式输出配置文件。每当您需要配置文件时,只需将其从 Config 部署(推送或拉取)到您想要的位置。请注意,我是 Config 团队的一员。

于 2018-02-17T06:12:11.410 回答