Файлы конфигурации для веб-приложения - загрузить один раз и сохранить где?
У меня есть куча свойств (конфигураций), которые могут меняться в зависимости от среды. Однако эти значения не меняются после развертывания веб-приложения. Итак, учтите, что существует файл 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-конфигурация уровня развертывания