Загрузить свойства Java внутри статического блока инициализатора - PullRequest
20 голосов
/ 25 июня 2009

У меня есть статический класс util, который выполняет некоторые манипуляции со строками для битовых данных. Перед использованием этого класса мне нужно инициализировать определенные статические переменные значениями, такими как имена пользователей и пароли, которые я предпочитаю хранить в файле .properties.

Я не очень знаком с тем, как загрузка файла .properties работает в Java, особенно вне контейнера * Spring DI *. Кто-нибудь может подсказать мне, как это можно сделать?

Спасибо!

Добавление: .properties точное местоположение файла неизвестно, но оно будет находиться на пути к классам. Сорта, как classpath:/my/folder/name/myproperties.propeties

Ответы [ 8 ]

26 голосов
/ 25 июня 2009

Сначала получите InputStream, из которого должны быть загружены свойства. Это может происходить из нескольких мест, включая некоторые из наиболее вероятных:

  • A FileInputStream, созданный с жестко заданным именем файла или указанным с помощью системного свойства . Имя может быть относительным (к текущему рабочему каталогу Java-процесс) или абсолют.
  • Файл ресурса (файл на пути к классам), полученный путем вызова getResourceAsStream на Class (относительно файла класса) или ClassLoader (относительно корня пути класса). Обратите внимание, что эти методы возвращают ноль, если ресурс отсутствует, вместо вызова исключения.
  • A 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); }
}
6 голосов
/ 25 июня 2009
  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");
  }
3 голосов
/ 25 июня 2009

Используйте либо:

CurrentClassName.class.getResourceAsStream 
new FileInputStream(File)

для получения входного потока в зависимости от того, находится ли класс в или нет classpath. Тогда используйте

Properties.load

для загрузки свойств.

2 голосов
/ 25 июня 2009

Это было давно, но если я правильно помню, вы просто делаете что-то вроде этого:

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

//For each property you need.
blah = prop.getProperty(propertyname);
1 голос
/ 08 июня 2017

для меня 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
    }
}
1 голос
/ 25 июня 2009

Хорошо со статическими свойствами имело бы смысл инициализировать их как 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);
    }
}

Если вы используете относительные имена путей, вы должны убедиться, что ваш путь к классам настроен правильно.

0 голосов
/ 20 февраля 2015

Я наконец сделал это, используя функцию 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();
      }
    }
    .
    .
    .
}
0 голосов
/ 13 июля 2014

Я согласен с @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;
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...