Подтвердить что ты не робот

Загрузка свойств java внутри статического блока инициализатора

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

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

Спасибо!

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

4b9b3361

Ответ 1

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

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

Ответ 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");
  }

Ответ 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

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

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

Ответ 6

Я согласен с @Daff, возможно, лучше использовать класс singleton... это то, что у меня есть в моем проекте для аналогичного требования, возможно, это может помочь:

клиенты класса могут использовать его следующим образом:

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

Я сделал это, наконец, используя getResourceAsStream() fuction, связанный с классом, в котором записывается статический кодовый блок.

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

Ответ 8

для меня 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
    }
}