在静态初始化程序块中加载 java 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1044855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Load java properties inside static initializer block
提问by xelurg
I have a static util class that does some string manipulation on a bit sensitive data.
Prior to use of this class I need to initialize certain static variables with values, such as usernames/password, that I prefer to store in a .properties
file.
我有一个静态 util 类,它对一些敏感数据进行一些字符串操作。在使用这个类之前,我需要用我更喜欢存储在.properties
文件中的值(例如用户名/密码)初始化某些静态变量。
I am not very familiar with how loading of .properties
file work in Java, especially outside of *Spring DI *container.
Anyone can give me a hand/insight on how this can be done?
我.properties
对 Java中文件的加载方式不是很熟悉,尤其是在 *Spring DI *container 之外。任何人都可以帮助我了解如何做到这一点?
Thank you!
谢谢!
Addition:.properties
file precise location is unknown, but it will be on the classpath. Sorta like classpath:/my/folder/name/myproperties.propeties
另外:.properties
文件的精确位置未知,但它会在类路径上。有点像classpath:/my/folder/name/myproperties.propeties
采纳答案by erickson
First, obtain an InputStream
from which the properties are to be loaded. This can come from a number of locations, including some of the most likely:
首先,获取InputStream
要从中加载属性的 。这可能来自多个位置,包括一些最有可能的位置:
- A
FileInputStream
, created with a file name that is hard-coded or specified via a system property.The name could be relative (to the current working directory of the Java process) or absolute. - A resource file (a file on the classpath), obtained through a call to
getResourceAsStream
on theClass
(relative to the class file) orClassLoader
(relative to the root of the class path). Note that these methods return null if the resource is missing, instead of raising an exception. - A
URL
, which, like a file name, could be hard-coded or specified via a system property.
- A
FileInputStream
,使用硬编码或通过系统属性指定的文件名创建。该名称可以是相对的(相对于 Java 进程的当前工作目录)或绝对的。 - 资源文件(类路径上的一个文件中),通过对一个呼叫所获得
getResourceAsStream
的Class
(相对于类文件)或ClassLoader
(相对于类路径的根目录)。请注意,如果资源丢失,这些方法将返回 null,而不是引发异常。 - A
URL
,与文件名一样,可以硬编码或通过系统属性指定。
Then create a new Properties
object, and pass the InputStream
to its load()
method. Be sure to close the stream, regardless of any exceptions.
然后创建一个新Properties
对象,并将 传递InputStream
给它的load()
方法。不管有什么异常,请务必关闭流。
In a class initializer, checked exceptions like IOException
must be handled. An unchecked exception can be thrown, which will prevent the class from being initialized. That, in turn, will usually prevent your application from running at all. In many applications, it might be desirable to use default properties instead, or fallback to another source of configuration, such as prompting a use in an interactive context.
在类初始值设定项中,IOException
必须处理检查异常之类的。可以抛出未经检查的异常,这将阻止类被初始化。反过来,这通常会阻止您的应用程序运行。在许多应用程序中,可能需要使用默认属性,或者回退到另一个配置源,例如在交互式上下文中提示使用。
Altogether, it might look something like this:
总而言之,它可能看起来像这样:
private static final String NAME = "my.properties";
private static final Properties config;
static {
Properties fallback = new Properties();
fallback.put("key", "default");
config = new Properties(fallback);
URL res = MyClass.getResource(NAME);
if (res == null) throw new UncheckedIOException(new FileNotFoundException(NAME));
URI uri;
try { uri = res.toURI(); }
catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); }
try (InputStream is = Files.newInputStream(Paths.get(uri))) { config.load(is); }
catch (IOException ex) { throw new UncheckedIOException("Failed to load resource", ex); }
}
回答by notnoop
Check out java.util.Properties.
You can use a static initializer. So on the top of the class you can do:
您可以使用静态初始化程序。所以在班级的顶部你可以做:
static {
Properties props = new Properties();
InputStream steam = ...; // open the file
props.load(stream);
// process properties content
String username = props.getProperty("username");
}
回答by stevedbrown
Use either:
使用:
CurrentClassName.class.getResourceAsStream
new FileInputStream(File)
to get the input stream depending on if the class is in or out of the classpath. Then use
根据类是在类路径中还是在类路径外来获取输入流。然后使用
Properties.load
to load the properties.
加载属性。
回答by patros
It's been a while, but if I remember correctly you just do something like this:
已经有一段时间了,但如果我没记错的话,您只需执行以下操作:
Properties prop = new Properties();
prop.load(new FileInputStream(filename));
//For each property you need.
blah = prop.getProperty(propertyname);
回答by Daff
Well with static Properties it would make sense to initialize them as a Singleton which will be loaded once in a class. Here's an example:
好吧,对于静态属性,将它们初始化为将在类中加载一次的单例是有意义的。下面是一个例子:
class Example
{
public final static String PROPSFILE = "test.properties";
private static Properties props;
protected static Properties getProperties()
{
if(props == null)
{
props = new Properties();
props.load(new FileInputStream(new File(PROPSFILE));
}
return props;
}
public static User getUser()
{
String username = getProperties().getProperty("username");
return new User(username);
}
}
If you use relative Pathnames you should make sure, that your classpath is setup righ.
如果您使用相对路径名,您应该确保您的类路径设置正确。
回答by Mosd
I agree with @Daff, maybe better to use singleton class...this what i have on my project for similar requirement, maybe it may help:
我同意@Daff,也许更好地使用单例类......这是我在我的项目中对类似要求的要求,也许它可能会有所帮助:
clients of the class can use it like this:
该类的客户可以这样使用它:
ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
System.out.format("source dir %s %n", configsLoader.getSourceDir());
and then the class:
然后是课程:
public class ConfigsLoader {
公共类 ConfigsLoader {
private String sourceDir;
private String destination;
private String activeMqUrl;
private static Logger log = Logger.getLogger(ConfigsLoader.class.getName());
private static ConfigsLoader instance = null;
private ConfigsLoader(String configFileName) {
log.info("loading configs");
Properties configs = new Properties();
try {
configs.loadFromXML(new FileInputStream(configFileName));
sourceDir = configs.getProperty("source.dir");
destination = configs.getProperty("destination");
activeMqUrl = configs.getProperty("activemqconnectionurl");
configs.setProperty("lastLoaded", new SimpleDateFormat("yyyy-M-d HH:mm").format(new Date()));
configs.storeToXML(new FileOutputStream(configFileName), "saving last modified dates");
} catch (InvalidPropertiesFormatException e) {
log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
} catch (FileNotFoundException e) {
log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
} catch (IOException e) {
log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
}
}
public static ConfigsLoader getInstance(String configFileName) {
if(instance ==null) {
instance = new ConfigsLoader(configFileName);
}
return instance;
}
public String getSourceDir() {
return sourceDir;
}
public void setSourceDir(String sourceDir) {
this.sourceDir = sourceDir;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getActiveMqUrl() {
return activeMqUrl;
}
public void setActiveMqUrl(String activeMqUrl) {
this.activeMqUrl = activeMqUrl;
}
}
}
回答by kung_fu_coder
I did this finally using getResourceAsStream() fuction associated with the class in which the static code block is being written.
我最终使用与正在编写静态代码块的类相关联的 getResourceAsStream() 函数来完成此操作。
//associate Property and ImputStream imports
public class A {
static Properties p;
static {
p = new Properties();
try {
InputStream in = A.class.getResourceAsStream("filename.properties");
p.load(in);
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException");
e.printStackTrace();
} catch (IOException e) {
System.out.println("IOException");
e.printStackTrace();
}
}
.
.
.
}
回答by electrobabe
for me MyClass.class.getClassLoader().getResourceAsStream(..)
did the trick:
对我来说MyClass.class.getClassLoader().getResourceAsStream(..)
做到了:
private static final Properties properties;
static {
Properties fallback = new Properties();
fallback.put(PROP_KEY, FALLBACK_VALUE);
properties = new Properties(fallback);
try {
try (InputStream stream = MyClass.class.getClassLoader().getResourceAsStream("myProperties.properties")) {
properties.load(stream);
}
} catch (IOException ex) {
// handle error
}
}