在静态初始化程序块中加载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); } } 
  1. 查看java.util.Properties 。

  2. 您可以使用静态初始化程序。 所以在课堂上你可以做到:

 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(); } } . . . }