Сделать свойства Java доступными для всех классов?

Я решил взять файл свойств для настройки некоторых параметров. Я использую следующий код, чтобы сделать объект свойств доступным в классе

Properties defaultProps = new Properties();
    try {
        FileInputStream in = new FileInputStream("custom.properties");
        defaultProps.load(in);
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

Нужно ли добавлять это к каждому классу? Вероятно, не потому, что тогда каждый класс откроет поток к этому файлу. Но я не уверен, как с этим справиться. Должен ли я создать класс MyProperties и создать экземпляр в любом классе, требующем свойств?

Спасибо заранее!

Ответ 1

После инициализации defaultProps вы можете сделать его содержимое доступным для других объектов в вашем приложении, например. посредством общедоступного статического метода доступа, например:

public class Config {
  private static Properties defaultProps = new Properties();
  static {
    try {
        FileInputStream in = new FileInputStream("custom.properties");
        defaultProps.load(in);
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
  public static String getProperty(String key) {
    return defaultProps.getProperty(key);
  }
}

Это самый простой подход, однако он создает дополнительную зависимость, которая усложняет модульное тестирование (если вы не предоставили метод в Config для установки объекта свойств mock для модульного тестирования).

Альтернативой является ввод defaultProps (или отдельных значений конфигурации из него) в каждый объект, который в ней нуждается. Однако это может означать, что вам нужно добавить дополнительные параметры к множеству методов, если иерархии вызовов глубоки.

Ответ 2

Если вам нужен только один экземпляр класса свойств, вы можете использовать singleton (anti?) -pattern.

Это будет выглядеть как класс:

public class MyProperties extends Properties {
    private static MyProperties instance = null;

    private MyProperties() {
    }

    public static MyProperties getInstance() {
        if (instance == null) {
            try {
                instance = new MyProperties();
                FileInputStream in = new FileInputStream("custom.properties");
                instance.load(in);
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return instance;
    }
}

Ответ 3

Почему бы не использовать статический ResourceBundle?

static final ResourceBundle myResources = 
          ResourceBundle.getBundle("MyResources", currentLocale);

Ответ 4

Слишком мало информации, чтобы определить, каким будет лучший способ справиться с этим. Вы можете просмотреть его с помощью аксессуаров или передать его в каждый класс, который требует его. Кроме того, вы можете вытащить свойства, необходимые каждому классу, и передать их значения в конструктор классов.

Ответ 5

Загрузите свойства один раз, используя и сохраняя свойства так, как могут извлекать другие классы. Если это класс MyProperties, который где-то ссылается на статическую переменную.

Ответ 6

Это особый случай сделать что-нибудь доступным во всем мире. Использование статических методов довольно плохое. Лучшее, но плохое решение использует шаблон сиглтон. Тестирование - самая большая проблема здесь. ИМХО, лучший способ - использовать инъекции зависимостей, хотя это может быть чрезмерным для небольших приложений.

Ответ 7

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

public class Properties {
  static {
    try {
      FileInputStream in = new FileInputStream("custom.properties");
      load(in);
      in.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  protected static void load(FileInputStream in) {
    // existing load functionality here
  }
}

Вам по-прежнему понадобится механизм внутренней памяти и механизм доступа. Они также должны быть отмечены static.

Ответ 8

Вместо загрузки свойств в каждом классе. Загрузите его где-нибудь вокруг main() и передайте его другим классам через их конструкторы.

Не делитесь ими по всему миру.  - Трудно проверить  - Против абстракции (глобальный доступ, DAO может получить доступ к пользовательским настройкам, его следует предотвратить, передав только то, что ему нужно... не все)  - Классы лгут, что им нужно