在静态初始化程序块中加载java属性
我有一个静态util类,它对位敏感数据进行一些字符串操作。 在使用这个类之前,我需要使用我喜欢存储在.properties
文件中的值(例如usernames / password)来初始化某些静态变量。
我不太熟悉.properties
文件的加载如何在Java中工作,特别是在* Spring DI *容器之外。 任何人都可以帮助我了解如何做到这一点?
谢谢!
另外: .properties
文件的精确位置未知,但它将在classpath上。 像classpath:/my/folder/name/myproperties.propeties
一样classpath:/my/folder/name/myproperties.propeties
首先,获取要从中加载属性的InputStream
。 这可能来自多个地点,包括一些最有可能的地点:
-
FileInputStream
,使用硬编码或通过系统属性指定的文件名创建。 名称可以是相对的(对于Java进程的当前工作目录)或绝对名称。 - 资源文件(类路径上的文件),通过调用
Class
(相对于类文件)或ClassLoader
(相对于类路径的根)的getResourceAsStream
获得。 请注意,如果缺少资源,这些方法将返回null,而不是引发exception。 - 一个
URL
,与文件名一样,可以通过系统属性进行硬编码或指定。
然后创建一个新的Properties
对象,并将InputStream
传递给它的load()
方法。 无论有什么例外,请务必关闭流。
在类初始化程序中,必须处理像IOException
这样的已检查exception。 可以抛出未经检查的exception,这将阻止该类被初始化。 反过来,这通常会阻止您的应用程序运行。 在许多应用程序中,可能需要使用默认属性,或者回退到另一个配置源,例如提示在交互式上下文中使用。
总而言之,它可能看起来像这样:
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); } }
-
查看java.util.Properties 。
-
您可以使用静态初始化程序。 所以在课堂上你可以做到:
static { Properties props = new Properties(); InputStream steam = ...; // open the file props.load(stream); // process properties content String username = props.getProperty("username"); }
使用:
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);
使用静态属性,将它们初始化为Singleton是有意义的,它将在类中加载一次。 这是一个例子:
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); } }
如果你使用相对路径名,你应该确保你的类路径设置得很好。
对我来说, 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 } }
我同意@Daff,也许更好地使用单例类…这就是我对我的项目的类似要求,也许它可能有所帮助:
该类的客户端可以像这样使用它:
ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml"); System.out.format("source dir %s %n", configsLoader.getSourceDir());
然后是class级:
公共类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-Md 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(); } } . . . }