Файлы конфигурации для веб-приложения - загрузить один раз и сохранить где?

У меня есть куча свойств (конфигураций), которые могут меняться в зависимости от среды. Однако эти значения не меняются после развертывания веб-приложения. Итак, учтите, что существует файл application.properties, который я хочу прочитать много раз во время нормального выполнения программы.

Я знаю, что, вероятно, я могу загрузить их во время запуска сервера. Однако каков наилучший способ доступа к ним из простых классов Java на серверной части? Эти бизнес-классы не имеют ничего общего с сервлетами и т. Д. И не зависят от веб-приложения.

Поэтому сегодня я загружаю свойства через ServletContext. Тогда что? Где я должен хранить их, чтобы они были легко доступны для других объектов без необходимости повторного выполнения fileInputStream.load?

Благодарю.

4 ответа

Решение

Реализовать ServletContextListener,

Вот базовый пример начала:

public class Config implements ServletContextListener {
    private static final String ATTRIBUTE_NAME = "config";
    private Properties config = new Properties();

    @Override
    public void contextInitialized(ServletContextEvent event) {
        try {
            config.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
        } catch (IOException e) {
            throw new SomeRuntimeException("Loading config failed", e);
        }
        event.getServletContext().setAttribute(ATTRIBUTE_NAME, this);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // NOOP.
    }

    public static Config getInstance(ServletContext context) {
        return (Config) context.getAttribute(ATTRIBUTE_NAME);
    }

    public String getProperty(String key) {
        return config.getProperty(key);
    }
}

который вы регистрируете следующим образом в web.xml:

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>

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

Config config = Config.getInstance(getServletContext());
String property = config.getProperty("somekey");

Подумав еще раз, эти свойства, таким образом, на 100% специфичны для бизнес-уровня, а не для самого веб-приложения? Затем ServletContextListener действительно неуклюжий и слишком тесно связанный. Просто дайте бизнес-слою свой собственный Config класс, который загружает свойства из classpath и кэширует его в некоторых static переменная (Map<String, Properties> может быть?).

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

Итак, предположим, у вас есть класс AppProperties:

public class AppProperties {
  private static Properties props;

  protected static loadProperties(File propsFile) {
    ... read from disk, and set props static member ...
  }

  public static getProperties() {
    return props;
  }
}

С вашего сервлета инициализатора, вы бы позвонили loadProperties читать свойства с диска. Затем в коде приложения для доступа к свойствам:

String myProp = AppProperties.getProperties().getProperty("myProp");

Поместите ваши классы / свойства конфигурации в файл jar, и поместите этот файл jar в WEB-INF/lib. Затем вы можете получить к ним доступ через обычные средства ресурсов classpath, куда вам нужно в вашем веб-приложении.

Вы можете использовать JNDI, если ваш сервер приложений поддерживает это.

Смотрите мой вопрос (и ответ) здесь: Spring-конфигурация уровня развертывания

Другие вопросы по тегам