wildfly:从配置目录中读取属性

我正在尝试从我的wildfly配置文件夹中的属性文件中读取部署特定信息。 我试过这个:

@Singleton @Startup public class DeploymentConfiguration { protected Properties props; @PostConstruct public void readConfig() { props = new Properties(); try { props.load(getClass().getClassLoader().getResourceAsStream("my.properties")); } catch (IOException e) { // ... whatever } } 

但显然这不起作用,因为配置文件夹不再在类路径中。 现在我找不到一个简单的方法来做到这一点。 我最喜欢的是这样的:

 @InjectProperties("my.properties") protected Properties props; 

到目前为止,我在网上找到的唯一解决方案是制作我自己的OSGi模块,但我相信必须有一种更简单的方法(没有OSGi!)。 谁能告诉我怎么样?

如果要显式读取配置目录中的文件(例如$WILDFLY_HOME/standalone/configurationdomain/configuration ),则系统属性中包含路径。 只需做System.getProperty("jboss.server.config.dir"); 并将您的文件名附加到该文件名以获取该文件。

你不会把它当作资源阅读,所以…

 String fileName = System.getProperty("jboss.server.config.dir") + "/my.properties"; try(FileInputStream fis = new FileInputStream(fileName)) { properties.load(fis); } 

然后将为您加载该文件。

此外,由于WildFly不再提供OSGi支持,我不知道创建OSGi模块将如何帮助您。

以下是使用CDI的完整示例,取自此站点 。

  1. 在WildFly配置文件夹中创建并填充属性文件

     $ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties 
  2. 将系统属性添加到WildFly配置文件。

     $ ./bin/jboss-cli.sh --connect [standalone@localhost:9990 /] /system-property=application.properties:add(value=${jboss.server.config.dir}/application.properties) 

这会将以下内容添加到您的服务器配置文件(standalone.xml或domain.xml):

    
  1. 创建用于加载和存储应用程序范围属性的单例会话bean

     import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.annotation.PostConstruct; import javax.ejb.Singleton; @Singleton public class PropertyFileResolver { private Logger logger = Logger.getLogger(PropertyFileResolver.class); private String properties = new HashMap<>(); @PostConstruct private void init() throws IOException { //matches the property name as defined in the system-properties element in WildFly String propertyFile = System.getProperty("application.properties"); File file = new File(propertyFile); Properties properties = new Properties(); try { properties.load(new FileInputStream(file)); } catch (IOException e) { logger.error("Unable to load properties file", e); } HashMap hashMap = new HashMap<>(properties); this.properties.putAll(hashMap); } public String getProperty(String key) { return properties.get(key); } } 
  2. 创建CDI限定符。 我们将在我们希望注入的Java变量上使用此注释。

     import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR }) public @interface ApplicationProperty { // no default meaning a value is mandatory @Nonbinding String name(); } 
  3. 创建生产者方法; 这会生成要注入的对象

     import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; import javax.inject.Inject; public class ApplicaitonPropertyProducer { @Inject private PropertyFileResolver fileResolver; @Produces @ApplicationProperty(name = "") public String getPropertyAsString(InjectionPoint injectionPoint) { String propertyName = injectionPoint.getAnnotated().getAnnotation(ApplicationProperty.class).name(); String value = fileResolver.getProperty(propertyName); if (value == null || propertyName.trim().length() == 0) { throw new IllegalArgumentException("No property found with name " + value); } return value; } @Produces @ApplicationProperty(name="") public Integer getPropertyAsInteger(InjectionPoint injectionPoint) { String value = getPropertyAsString(injectionPoint); return value == null ? null : Integer.valueOf(value); } } 
  4. 最后将属性注入您的一个CDI bean

     import javax.ejb.Stateless; import javax.inject.Inject; @Stateless public class MySimpleEJB { @Inject @ApplicationProperty(name = "docs.dir") private String myProperty; public String getProperty() { return myProperty; } } 

您可以做的最简单的事情是使用引用属性文件的-P选项运行standalone.sh (您需要一个URL file:/path/to/my.properties ,或者将文件放在$WILDFLY_HOME/bin )。

然后,文件中的所有属性都将作为系统属性加载。

要将配置属性注入到应用程序类中,请查看DeltaSpike配置 ,它支持不同的属性源,如系统属性,环境变量,JNDI条目,并隐藏应用程序中的特定源。

或者,为了避免设置系统属性(在部署到WildFly实例的所有应用程序都可见的情况下将是全局属性),您还可以为DeltaSpike定义从任何给定位置读取属性文件的自定义属性源,以及这些属性将在您的申请本地。

听起来您正在尝试解决的问题是管理不同(但可能类似)的配置文件,以便在不同环境(即生产,QA甚至不同客户)中运行您的应用程序。 如果是这种情况,请查看Jfig http://jfig.sourceforge.net/ 。 它可以避免在类路径之外存储属性文件的需要(但你仍然可以)。

所需要的是配置文件的分层方法。 可以在基本文件中维护未更改的百分之九十的配置值。 其他百分之十(或更少)可以在他们自己的不同配置文件中维护。 在运行时,文件彼此叠加,以提供灵活,可管理的配置。 例如,在开发环境中,myhost.config.xml与dev.config.xml和base.config.xml组合以形成我的唯一配置。

然后,每个配置文件可以在版本控制中维护,因为它们具有唯一的名称。 基值更改时,只需要修改基本文件,并且很容易看到版本之间的差异。 另一个主要好处是在部署之前将对基本配置文件的更改进行详尽测试。

 InputStream in = null; File confDir = new File(System.getProperty("jboss.server.config.dir")); File fileProp = new File(confDir, "my.properties"); try{ //teste fileProp.exists etc. in = new FileInputStream(fileProp); Properties properties = new Properties(); properties.load(in); //You should throws or handle FileNotFoundException and IOException }finally{ try{ in.close(); }catch(Exception ignored){ } } 
Interesting Posts