什么是Java EE 7属性文件配置的最佳实践建议? [英] What are Best Practice Recommendations for Java EE 7 Property File Configuration?

查看:100
本文介绍了什么是Java EE 7属性文件配置的最佳实践建议?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序配置在现代Java EE应用程序中的位置?人们有什么最佳实践建议?



通过应用程序配置,我的意思是设置连接设置到其他盒子上的服务,包括外部设备(例如Twitter和我们的内部Cassandra服务器......用于诸如主机名,凭证,重试尝试之类的东西)以及与业务逻辑相关的东西(人们可能想要在类中存储常量的东西,例如某些东西过期等等)。



假设:


  1. 我们正在部署到Java EE 7服务器(Wildfly 8.1)使用单个EAR文件,其中包含多个战争和一个ejb-jar。

  2. 我们将部署到各种环境:单元测试,本地开发安装,UAT的基于云的基础架构,压力测试和生产环境。 我们的许多属性会因每种环境而异。

  3. 如果这是人们推荐的最佳做法,我们不反对将属性配置耦合到DI框架。

  4. 所有这些都是针对新开发的,因此我们不必遵守传统要求或限制。我们非常关注当前的现代最佳实践。

配置是属于EAR内部还是外部?



如果在外部,哪里以及如何最好地可靠地访问它们?



如果在EAR里面 ,我们可以将它存储在类路径中的任何位置,以便在执行期间轻松访问。但是我们必须在每次配置更改时重新组装(并且可能重新构建)。由于我们将拥有多个环境,因此我们需要一种方法来区分EAR中的文件。我在这里看到两个选项:


  1. 利用预期的文件名(例如 cassandra.properties 然后构建多个特定于环境的EAR(例如 appxyz-PROD.ear )。

  2. 构建一个EAR(例如 appxyz.ear )并将所有各种环境配置文件放入其中,为每个配置文件名附加一个环境变量(例如 cassandra-PROD.properties )。当然还要添加一个环境变量(到vm或其他),这样代码就会知道要拾取哪个文件。

什么是人们可以推荐解决这一共同挑战的最佳做法吗?



谢谢。

解决方案

我不知道什么是最佳实践,但这就是我们的工作。



(但请注意,这仅适用于每个服务器每个应用程序的一次安装,并且当每个服务器想要使用多个部署时,例如多租户部署时,将会失败)。 / p>

CDI注入属性值



我们使用一种稍微复杂的CDI注入方法从<$ c注入配置值$ c> .properties 直接将文件放入bean中,如下所示:

  @Inject @ConfigurationValue(value =amazonS3FileContentsAccessKey)
private String accessKey;

相应的 @Producer bean读取配置文件从类路径和给定的本地位置:



全局/本地 .properties 文件




  1. 每个EAR在类路径中包含一个全局 .properties 文件,用于配置值通过环境很少改变和/或通常保持一致(例如某些东西过期的天数)。此外,全局配置文件包含合理的默认值(例如,对于数据库服务器主机名, localhost )。在源树中维护全局属性文件(有多个,见下文)。

  2. 对于每个开发环境/安装/服务器/部署,那里(可能)是一个本地属性文件,其中包含覆盖全局配置设置的本地设置,例如数据库名称,密码等。

本地属性文件的预期路径在全局配置文件中配置(例如, /etc/myapp/local.properties )或 C:\ myapp \ local.properties



实际上,我们甚至允许替换一些变量本地配置文件的文件名,例如 $ {hostname} 。最初的想法是,通过主机名( local.machineA.properties local)区分它们,也可以在某些中央源控件中维护本地属性。 machineB.properties ),但我们目前不使用它,因为我们的生产设置在所有机器上都是相同的(Amazon S3密钥,数据库密码/主机等)。



组装开发,测试,生产



我们根据使用Maven配置文件的开发阶段组装不同的EAR。

On assemply,所需的 global。$ {profile.name} .properties 文件(其中 profile.name 是,例如, dev production )被复制到预期的 global.properties 类路径中的文件。



例如, dev 测试共享一个共同的AmazonS3秘密/存储桶,为 configuration.dev.properties 文件中的所有开发人员配置一次le $ code> configuration.production.properties 不包含我们的生产密钥。



此外,我们的 dev 测试环境已启用并配置调试,例如 web.xml ,但当然 staging 生产还没有。我们的基于 .properties 的方法无法更改 web.xml 等文件,但使用Maven构建配置文件很容易。


Where does application configuration belong in modern Java EE applications? What best practice(s) recommendations do people have?

By application configuration, I mean settings like connectivity settings to services on other boxes, including external ones (e.g. Twitter and our internal Cassandra servers...for things such as hostnames, credentials, retry attempts) as well as those relating business logic (things that one might be tempted to store as constants in classes, e.g. days for something to expire, etc).

Assumptions:

  1. We are deploying to a Java EE 7 server (Wildfly 8.1) using a single EAR file, which contains multiple wars and one ejb-jar.
  2. We will be deploying to a variety of environments: Unit testing, local dev installs, cloud based infrastructure for UAT, Stress testing and Production environments. Many of our properties will vary with each of these environments.
  3. We are not opposed to coupling property configuration to a DI framework if that is the best practice people recommend.
  4. All of this is for new development, so we don't have to comply with legacy requirements or restrictions. We're very focused on the current, modern best practices.

Does configuration belong inside or outside of an EAR?

If outside of an EAR, where and how best to reliably access them?

If inside of an EAR we can store it anywhere in the classpath to ease access during execution. But we'd have to re-assemble (and maybe re-build) with each configuration change. And since we'll have multiple environments, we'd need a means to differentiate the files within the EAR. I see two options here:

  1. Utilize expected file names (e.g. cassandra.properties) and then build multiple environment specific EARs (eg. appxyz-PROD.ear).
  2. Build one EAR (eg. appxyz.ear) and put all of our various environment configuration files inside it, appending an environment variable to each config file name (eg cassandra-PROD.properties). And of course adding an environment variable (to the vm or otherwise), so that the code will know which file to pickup.

What are the best practices people can recommend for solving this common challenge?

Thanks.

解决方案

I don't know what is best practice, but here is what we do.

(Note however that this only works well for one installation per application per server and will fail when one wants to use multiple deployments per server, say for multitenancy deployments).

CDI injection of properties values

We use a somewhat sophisticated CDI injection approach to inject configuration values from .properties files directly into beans, like this:

@Inject @ConfigurationValue(value="amazonS3FileContentsAccessKey")
private String accessKey;

The corresponding @Producer bean reads configuration files from the class path and from a given "local" location:

global/local .properties files

  1. Each EAR contains a "global" .properties file on the class path for configuration values that change seldom and/or usually remain consistent through environments (such as days for something to expire). Further, the global configuration file contains sane default values (e.g. "localhost" for database server hostname). The global properties files (there are multiple, see below) are maintained in the source tree.
  2. For every development environment/installation/server/deployment, there (possibly) is a "local" properties file that contains the local settings that overwrite the global configuration's settings, e.g., database names, passwords etc.

The expected path to "local" properties files is configured in the global configuration file (e.g., /etc/myapp/local.properties) or C:\myapp\local.properties.

Actually, we even allow substitution of some variables in the filename for the local configuration files, such as "${hostname}". The original idea was that the local properties could also be maintained in some central source control by distinguishing them by hostname (local.machineA.properties, local.machineB.properties), but we don't use that at the moment, because our production settings are the same on all machines (Amazon S3 keys, database password/host etc).

Assembling for dev, testing, production

We assemble different EARs depending on the stage of development using Maven profiles.
On assemply, the desired global.${profile.name}.properties file (where profile.name is, e.g., dev or production) is copied to the expected global.properties file in the classpath.

For example, dev and testing share a common AmazonS3 secret/bucket, which is configured once for all developers in the configuration.dev.properties file, while the configuration.production.properties does not contain our production keys.

Furthermore, our dev and testing environments have debugging enabled and configured in, say web.xml, but of course staging and production have not. Our .properties-based approach cannot change files such as web.xml, but with Maven build profiles it's easy.

这篇关于什么是Java EE 7属性文件配置的最佳实践建议?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆