wildfly:从配置目录读取属性
Posted
技术标签:
【中文标题】wildfly:从配置目录读取属性【英文标题】:wildfly: reading properties from configuration directory 【发布时间】:2015-03-13 05:53:59 【问题描述】:我正在尝试从 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 配置文件夹中,那么它是全局的,而不是特定于部署的。这有点令人困惑...... 也许我误用了“特定于部署”这个词。该文件位于 wildfly/standalone/configuration 文件夹中。 如果我记得清楚的话,我曾经在这个文件夹下有我的配置,我只是通过简单地做 File("myfile.properties") 解析到这个路径(我想这可能是工作目录老板) 【参考方案1】:您可以做的最简单的事情是运行 standalone.sh
并使用 -P
选项引用您的属性文件(您需要一个 URL file:/path/to/my.properties
,或将文件放入 $WILDFLY_HOME/bin
)。
然后文件中的所有属性都将作为系统属性加载。
关于将配置属性注入您的应用程序类,请查看DeltaSpike Configuration,它支持不同的属性源,如系统属性、环境变量、JNDI 条目并隐藏您的应用程序的特定源。
另外,为了避免设置系统属性(这对于部署到 WildFly 实例的所有应用程序而言都是全局的),您还可以为 DeltaSpike 从任何给定位置读取属性文件定义自定义属性源,这些属性将是您的应用程序的本地属性。
【讨论】:
所以我在 deltaspike 网站上找到了这个 sn-p:@Inject @InjectableResource("myfile.properties") private InputStream inputStream;我还没有下载 DeltaSpike,所以我还不能测试它。我的问题是:如果配置文件夹不在类路径中并且我没有配置查找位置,DeltaSpike 如何从配置文件夹中读取此文件? WildFly 读取文件,而不是 DeltaSpike - DeltaSpike 读取 WildFly 设置的系统属性。要通过 DeltaSpike(我的回答的最后一段)读取文件,您需要实现自定义 DeltaSpike 配置源并将其注册到 DeltaSpike。您将使用文件路径,而不是类路径来访问该文件。 感谢您的输入,但对我来说有点太复杂了。 this github repo 显示了 Harald 在代码中的含义【参考方案2】:如果您想从配置目录(例如$WILDFLY_HOME/standalone/configuration
或domain/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 模块对您有什么帮助。
【讨论】:
这么简单,为什么不是我自己想出来的呢?我在考虑类路径。 输入流保持打开状态。不要直接传递给 properties.load 你是对的@Wender,但老实说,我只是想把它当作伪代码。 注意 jboss.server.config.dir 与 jboss.domain.config.dir 不同。如果您的应用同时部署到独立环境和域环境,则需要进行一些调整。【参考方案3】:这是一个仅使用 CDI 的完整示例,取自 site。
在 WildFly 配置文件夹中创建并填充属性文件
$ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties
向 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)中:
<system-properties>
<property name="application.properties" value="$jboss.server.config.dir/application.properties"/>
</system-properties>
创建加载和存储应用程序范围属性的单例会话 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);
创建 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();
创建生产者方法;这会生成要注入的对象
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);
最后将属性注入您的 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;
【讨论】:
【参考方案4】:听起来您要解决的问题是管理不同(但可能相似)的配置文件,以便在不同环境(即生产、QA 甚至不同的客户)中运行您的应用程序。如果是这种情况,请查看 Jfig http://jfig.sourceforge.net/ 。它将消除将属性文件存储在类路径之外的需要(但您仍然可以)。
需要的是对配置文件采用分层方法。百分之九十不变的配置值可以保存在一个基本文件中。其他 10%(或更少)可以保存在他们自己不同的配置文件中。在运行时,这些文件相互叠加,以提供灵活、可管理的配置。例如,在开发环境中 myhost.config.xml 与 dev.config.xml 和 base.config.xml 结合形成我的唯一配置。
每个配置文件都可以在版本控制中维护,因为它们具有唯一的名称。基础值变化时只需要修改基础文件,很容易看出版本之间的差异。另一个主要好处是,对基本配置文件的更改将在部署之前进行详尽的测试。
【讨论】:
【参考方案5】: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)
【讨论】:
【参考方案6】:为避免此类问题,问题是在 VM 参数中设置 jboss.server.config.dir
,如下所示:
-Djboss.server.config.dir="[jboss_repository]/server/[default-all-standard-standalone]/conf" –server
【讨论】:
添加更多描述。【参考方案7】:如果你有standalone.xml 属性:
<property name="my.properties" value="propertyValue"/>
你可以用以下方式阅读它:
static final String MY_PROPERTY = System.getProperty("my.properties");
或者,如果您在 web.xml 中指定上下文参数,例如:
<context-param>
<param-name>MyProperty</param-name>
<param-value>MyPropertyValue</param-value>
</context-param>
你可以在 Java bean 中阅读它:
String myProperty= getServletContext().getInitParameter("MyProperty");
【讨论】:
以上是关于wildfly:从配置目录读取属性的主要内容,如果未能解决你的问题,请参考以下文章