在静态初始化程序块中加载java属性

时间:2009-06-25 16:23:24

标签: java properties

我有一个静态util类,它对位敏感数据执行一些字符串操作。 在使用这个类之前,我需要使用值(例如用户名/密码)初始化某些静态变量,我希望将其存储在.properties文件中。

我不太熟悉如何在Java中加载.properties文件,特别是在* Spring DI *容器之外。 任何人都可以帮我了解如何做到这一点?

谢谢!

添加: .properties文件的精确位置未知,但它将在类路径上。排序类似classpath:/my/folder/name/myproperties.propeties

8 个答案:

答案 0 :(得分:26)

首先,获取要加载属性的InputStream。这可能来自许多地方,包括一些最有可能的地方:

  • 使用文件名创建的FileInputStream,该文件名是硬编码的或通过system property.指定的名称可以是相对的(对于Java进程的当前工作目录)或绝对名称。
  • 资源文件(类路径上的文件),通过调用Class上的getResourceAsStream(相对于类文件)或ClassLoader(相对于根目录)获得课程路径)。请注意,如果缺少资源,这些方法将返回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); }
}

答案 1 :(得分:6)

  1. 查看java.util.Properties

  2. 您可以使用静态初始值设定项。所以在课堂上你可以做到:

  3. 
     static {
        Properties props = new Properties();
        InputStream steam = ...; // open the file
        props.load(stream);
    
        // process properties content
        String username = props.getProperty("username");
      }
    

答案 2 :(得分:3)

使用:

CurrentClassName.class.getResourceAsStream 
new FileInputStream(File)

获取输入流取决于类是否在类路径中。然后使用

Properties.load

加载属性。

答案 3 :(得分:2)

已经有一段时间了,但如果我没记错的话,你只需要这样做:

Properties prop = new Properties();
prop.load(new FileInputStream(filename));

//For each property you need.
blah = prop.getProperty(propertyname);

答案 4 :(得分:1)

使用静态属性,将它们初始化为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);
    }
}

如果您使用相对路径名,则应确保您的类路径已设置为righ。

答案 5 :(得分:1)

对我来说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
    }
}

答案 6 :(得分:0)

我同意@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;
}

}

答案 7 :(得分:0)

我最终使用与正在编写静态代码块的类关联的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();
      }
    }
    .
    .
    .
}