在静态初始化块中加载 java 属性
Posted
技术标签:
【中文标题】在静态初始化块中加载 java 属性【英文标题】:Load java properties inside static initializer block 【发布时间】:2010-11-05 21:39:28 【问题描述】:我有一个静态实用程序类,它对一些敏感数据进行一些字符串操作。
在使用这个类之前,我需要用值初始化某些静态变量,例如用户名/密码,我更喜欢将它们存储在 .properties
文件中。
我不太熟悉在 Java 中加载 .properties
文件的工作方式,尤其是在 *Spring DI *container 之外。
任何人都可以帮助我了解如何做到这一点?
谢谢!
补充: .properties
文件的精确位置未知,但它会在类路径上。有点像classpath:/my/folder/name/myproperties.propeties
【问题讨论】:
您提到了 Spring - 您是否在应用程序中使用包含此静态实用程序类的框架? 嗯,这有点奇怪。类将在使用 spring 容器的应用程序中使用。然而,类本身不会使用 spring 连接,它需要只是一个静态实用程序类,由 Spring 连接的工作线程调用。我可以修改工作线程,但我不能修改这些线程的接线(所以我不能使用 PropertyPlaceHolderConfigurer)......嗯,这有意义吗? :) 【参考方案1】:首先,获取要从中加载属性的InputStream
。这可能来自多个位置,包括一些最有可能的位置:
FileInputStream
,使用硬编码或通过system property. 指定的文件名创建。名称可以是相对的(相对于 Java 进程的当前工作目录)或绝对的。
资源文件(类路径上的文件),通过在Class
(相对于类文件)或ClassLoader
(相对于类路径的根)上调用getResourceAsStream
获得。请注意,如果资源丢失,这些方法将返回 null,而不是引发异常。
URL
,与文件名一样,可以硬编码或通过系统属性指定。
然后创建一个新的Properties
对象,并将InputStream
传递给它的load()
方法。一定要关闭流,不管有什么异常。
在类初始化器中,必须处理像IOException
这样的已检查异常。可以抛出未经检查的异常,这将阻止类被初始化。反过来,这通常会阻止您的应用程序运行。在许多应用程序中,可能需要改用默认属性,或者回退到其他配置源,例如在交互式上下文中提示使用。
总而言之,它可能看起来像这样:
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);
【讨论】:
【参考方案2】:查看java.util.Properties。
您可以使用静态初始化程序。所以在课堂上你可以做:
static
Properties props = new Properties();
InputStream steam = ...; // open the file
props.load(stream);
// process properties content
String username = props.getProperty("username");
【讨论】:
对不起,我猜你在我做的时候已经在格式化代码了。 您可能需要一些异常处理,因为我不认为可以从静态块中抛出异常。 RuntimeExceptions 可以从静态块中抛出。您将需要处理文件操作的检查异常。 这里建议的实现主要是为了说明。要使其达到生产质量,您需要处理与文件相关的异常(例如安全性、存在性、IOException),在 finally 块中关闭连接,处理加密(我希望他不要以明文形式保存密码)等 【参考方案3】:使用任一:
CurrentClassName.class.getResourceAsStream
new FileInputStream(File)
根据类是否在类路径中来获取输入流。然后使用
Properties.load
加载属性。
【讨论】:
【参考方案4】:已经有一段时间了,但如果我没记错的话,你只需这样做:
Properties prop = new Properties();
prop.load(new FileInputStream(filename));
//For each property you need.
blah = prop.getProperty(propertyname);
【讨论】:
【参考方案5】:对于静态属性,将它们初始化为将在类中加载一次的单例是有意义的。这是一个例子:
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);
如果您使用相对路径名,您应该确保您的类路径设置正确。
【讨论】:
那不是单例。它只是一个静态变量和方法。该问题不需要公开访问属性,但需要从属性文件初始化静态成员。 好吧,我个人不喜欢静态初始化,因为它在我正在从事的项目中造成了一些麻烦。我建议尽可能使用至少静态工厂方法(我为此更新了示例)。但确实,这实际上不是问题。【参考方案6】:对我来说 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
【讨论】:
【参考方案7】:我同意@Daff,也许最好使用单例类...这是我在项目中对类似要求的要求,也许它可能会有所帮助:
类的客户可以这样使用它:
ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
System.out.format("source dir %s %n", configsLoader.getSourceDir());
然后是班级:
公共类 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;
【讨论】:
【参考方案8】:我最终使用与正在编写静态代码块的类关联的 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();
.
.
.
【讨论】:
以上是关于在静态初始化块中加载 java 属性的主要内容,如果未能解决你的问题,请参考以下文章