如何将Java EEconfiguration参数存储在EAR或WAR之外?
我想存储Web项目之外的Web项目的configuration(ear / war文件)。 应用程序不应该知道在哪个容器中运行(WebSphere / JBoss等)。
处理这个问题的最好方法是什么?
JNDI是一个干净的方式吗? 如果JNDI可以解决我的问题,我应该如何configuration它? (自定义对象?)
在我的情况下,只有简单的Key =>值对(string,string)的SOAP / WS端点。
看到这个问题读取WAR文件之外的属性文件。
看到这个问题从JNDI读取variables值。 我相信这是最好的解决scheme。 你可以用下面的代码读取一个stringvariables:
Context initialContext = new InitialContext(); String myvar = (String) initialContext.lookup("java:comp/env/myvar");
上面的代码将适用于所有容器。 在Tomcat中,在conf / server.xml中声明以下内容:
<GlobalNamingResources ...> <Environment name="myvar" value="..." type="java.lang.String" override="false"/> </GlobalNamingResources>
以上将创build一个全球资源。 也可以在应用程序的上下文中定义资源。 在大多数容器中,JNDI资源通过MBeanspipe理控制台可用。 其中一些提供了一个graphics界面来编辑它们。 在进行更改时,至多需要重新启动应用程序。
如何定义和编辑JNDI资源是特定于容器的。 configuration器/pipe理员的工作是应用适当的设置。
这些是JNDI提供的好处:
- 您可以在WAR / EAR文件中定义参数的默认值。
- 参数在容器中很容易configuration。
- 修改参数的值时,不需要重新启动容器。
在为不同的开发人员部署Web应用程序时,我们有类似的configuration要求,在Amazon的EC2上:我们如何将configuration从二进制代码中分离出来? 根据我的经验,JNDI太复杂了,在使用的容器之间差别太大。 另外,手工编辑XML非常容易出现语法错误,所以这个想法被抛弃了。 我们用一些基于以下规则的devise来解决这个问题:
1)只应使用简单的名称=值条目
2)只能通过更改一个参数来加载新的configuration
3)我们的WAR二进制文件必须可重新configuration而不需要重新打包
4)敏感参数(密码)永远不会打包在二进制文件中
对所有configuration使用.properties文件,并使用System.getProperty("domain");
加载适当的属性文件,我们能够满足要求。 但是,系统属性并不指向文件URL,而是我们创build了一个我们称之为“域”的概念来指定要使用的configuration。 configuration的位置总是:
$HOME/appName/config/$DOMAIN.properties
。
所以,如果我想使用我自己的configuration来运行我的应用程序,我通过将域设置为我的名字来启动应用程序:
-Ddomain=jason
在启动时,应用程序加载文件:
/home/jason/appName/config/jason.properties
这让开发人员可以共享configuration,因此我们可以重新创build应用程序的相同状态以进行testing和部署,而无需重新编译或重新打包。 然后,域值将用于从捆绑的WAR之外的标准位置加载.properties。
我可以通过使用生产configuration完全重新创build我的工作站上的生产环境,如:
-Ddomain=ec2
这将加载:
/home/jason/appName/config/ec2.properties
这个设置使我们能够在每个环境中使用不同的configuration,完成具有一组编译的二进制文件的dev / QA / release周期。 密码/等捆绑在二进制文件没有风险,人们可以共享他们的configuration重新创build我们所看到的问题。
我使用一个环境variables来指向一个URL(可能是一个文件:/ / URL),其中有我的configuration。 这是非常简单的设置,不需要JNDI的基础设施。
下面是一些示例代码(从内存中键入 – 我没有编译/testing过):
public void loadConfiguration() { String configUrlStr = System.getenv("CONFIG_URL"); // You'd want to use a more // Specific variable name. if(configUrlStr == null || configUrlStr.equals("") { // You would probably want better exception handling, too. throw new RuntimeException("CONFIG_URL is not set in the environment."); } try { URI uri = new URI(configUrlStr); File configFile = new File(uri); if(!configFile.exists()) { throw new RuntimeException("CONFIG_URL points to non-existant file"); } if(!configFile.canRead()) { throw new RuntimeException("CONFIG_URL points to a file that cannot be read."); } this.readConfiguration(configFile); } catch (URISyntaxException e) { throw new RuntimeException("Malformed URL/URI in CONFIG_URL"); } }
你可以只存储然后是一个正常的java属性文件是在类path上,只是加载属性?
这是直截了当,非常简单..除非我失去了一些东西
我最喜欢的地方是:环境variables和属性文件(如上面的Jared和kgiannakakis所build议的)。
数据库表存储环境属性
但是另一个更简单的解决scheme是使数据库表存储环境属性。
如果你的应用使用数据库
- 这是相对容易的设置
- 提供真正简单的方法来控制/更改值
- 通过将其作为数据库脚本的一部分,它可以很好地集成到stream程中