在静态初始值设定项块中加载java属性
我有一个静态util类,它对一些敏感数据进行字符串操作。 在使用这个类之前,我需要用我喜欢存储在在静态初始值设定项块中加载java属性,java,properties,Java,Properties,我有一个静态util类,它对一些敏感数据进行字符串操作。 在使用这个类之前,我需要用我喜欢存储在.properties文件中的值(例如用户名/密码)初始化某些静态变量 我不太熟悉在Java中加载.properties文件是如何工作的,尤其是在*springdi*容器之外。 任何人都可以帮助我/了解如何做到这一点 谢谢大家! 添加:.properties文件的精确位置未知,但它将位于类路径上。排序类似于classpath:/my/folder/name/myproperties.propertie
.properties
文件中的值(例如用户名/密码)初始化某些静态变量
我不太熟悉在Java中加载.properties
文件是如何工作的,尤其是在*springdi*容器之外。
任何人都可以帮助我/了解如何做到这一点
谢谢大家!
添加:.properties
文件的精确位置未知,但它将位于类路径上。排序类似于classpath:/my/folder/name/myproperties.properties
CurrentClassName.class.getResourceAsStream
new FileInputStream(File)
根据类在类路径中还是在类路径外获取输入流。然后使用
Properties.load
加载属性。已经有一段时间了,但如果我没记错的话,您可以这样做:
Properties prop = new Properties();
prop.load(new FileInputStream(filename));
//For each property you need.
blah = prop.getProperty(propertyname);
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); }
}
ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
System.out.format("source dir %s %n", configsLoader.getSourceDir());
对于静态属性,将它们初始化为一个在类中加载一次的单例是有意义的。下面是一个例子:
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);
}
}
如果使用相对路径名,则应确保类路径已正确设置。首先,获取要从中加载属性的
InputStream
。这可能来自多个位置,包括一些最可能的位置:
- A,使用硬编码或通过指定的文件名创建。该文件名可以是相对的(相对于Java进程的当前工作目录)或绝对的
- 资源文件(类路径上的文件),通过调用(相对于类文件)或(相对于类路径的根)上的
获得。请注意,如果资源丢失,这些方法将返回null,而不是引发异常getResourceAsStream
- 与文件名类似,可以硬编码或通过系统属性指定
Properties
对象,并将InputStream
传递给它的方法。不管有什么异常,请确保关闭流
在类初始值设定项中,必须处理检查过的异常,如IOException
。可以引发未检查的异常,这将阻止初始化该类。这反过来通常会阻止应用程序运行。在许多应用程序中,可能希望改用默认属性,或者回退到另一个配置源,例如在交互上下文中提示使用
总之,它可能看起来像这样:
Properties prop = new Properties();
prop.load(new FileInputStream(filename));
//For each property you need.
blah = prop.getProperty(propertyname);
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); }
}
ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
System.out.format("source dir %s %n", configsLoader.getSourceDir());
我同意@Daff,也许最好使用singleton类…这是我在项目中针对类似要求所做的工作,可能会有帮助: 该类的客户端可以这样使用它:
Properties prop = new Properties();
prop.load(new FileInputStream(filename));
//For each property you need.
blah = prop.getProperty(propertyname);
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); }
}
ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
System.out.format("source dir %s %n", configsLoader.getSourceDir());
然后是课堂:
公共类配置加载程序{
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;
}
}最后,我使用与编写静态代码块的类相关联的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();
}
}
.
.
.
}
对我来说,
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
}
}
您提到了Spring——您是否在应用程序中使用了包含此静态实用程序类的框架?嗯,这有点奇怪。类将在使用spring容器的应用程序中使用。然而,类本身不会使用spring连接,它只需要是一个静态实用程序类,由spring连接的工作线程调用get。我可以修改工作线程,但我不能修改这些线程的连接(因此我不能使用PropertyPlaceHolderConfigure)…嗯,这有什么意义吗?:)抱歉,我猜您在我执行此操作时已经在格式化代码。您可能需要一些异常处理,因为我认为不能从静态块中引发异常。RuntimeExceptions可以从静态块中引发。您需要处理文件操作的已检查异常。此处建议的实现主要用于说明。为了提高生产质量,您需要处理与文件相关的异常(例如,安全性、存在性、IOException)、在finally块中关闭连接、处理加密(我希望他不会以明文形式保存密码),等等,这不是一个单一的问题。它只是一个静态变量和方法。这个问题不需要公共访问属性,而是需要从属性文件初始化静态成员。就我个人而言,我不喜欢静态初始化,因为它在我正在进行的项目中造成了一些麻烦。我建议在可能的情况下至少使用静态工厂方法(为此我更新了示例)。但事实上,这并不是问题所在。