#spring-boot
#весенняя загрузка
Вопрос:
Я модернизирую устаревшее веб-приложение. Одна из сложностей в этом приложении — модель конфигурации. В настоящее время у каждого клиента есть отдельный экземпляр приложения с отдельными свойствами конфигурации для каждого экземпляра. В настоящее время свойства хранятся в Tomcat context.xml , и есть помощник JNDI для извлечения этих свойств при запуске. Поскольку один экземпляр Tomcat = один context.xml , это работает. Но теперь нам нужен один экземпляр (или кластер экземпляров) для всех клиентов.
Я думаю, что обычно это делается во время сеанса. Но в этом случае это был бы большой рефакторинг. Значения конфигурации хранятся в pojo со статическими установщиками и получателями, которые часто вызываются по всей кодовой базе. Помощник JNDI устанавливает конфигурацию в pojo при запуске, и именно так приложение находит свои значения конфигурации.
Мы делаем небольшие шаги при разработке, чтобы улучшить эту модель, а не проводить большой рефакторинг. Итак, цель состоит в том, чтобы изменить как можно меньше, двигаясь в правильном направлении. Одной из вещей, которые я рассматривал, было использование профилей весенней загрузки. Вместо отдельного экземпляра для каждого клиента может быть профиль весенней загрузки для каждого клиента. Затем, при каждом HTTP-запросе, фильтр сервлетов может активировать соответствующий профиль, наблюдая за пользователем и активируя его профиль на время выполнения запроса, который, я надеюсь, сможет затем вводить значения в статические установщики из фильтра.
Я знаю, что это ненормально, но я пытаюсь мыслить нестандартно.
Я знаю о ConfigurableEnvironment.setActiveProfiles. В чем я не уверен, так это в том, будет ли это активно вводить изменения значений свойств после фазы начальной загрузки, а также может ли это вызвать проблемы с производительностью или по какой-либо другой причине звучит безумно.
Ответ №1:
Из документации Spring:
Вы можете программно установить активные профили, вызвав
SpringApplication.setAdditionalProfiles(…)
их перед запуском вашего приложения. Также можно активировать профили с помощьюConfigurableEnvironment
интерфейса Spring.
Ответ №2:
Это не имеет ничего общего с spring profiles! Вы можете управлять ими программно, но в какой-то момент у вас есть один контекст spring в вашей JVM (приложении). Вы хотите работать с пользовательскими свойствами, не так ли? Это для каждого запроса или, скорее, для области сеанса, а не для области приложения! Я предлагаю вам следующий сценарий:
1.) после аутентификации вашего клиента сохраните его значения в экземпляре CustomerConfig (не статическом!) И сохраните этот customerConfig в атрибутах запроса или сеанса
2.) вы можете сделать это в HttpFilter :
if (session.isNew)
{ // read customerConfig from DB or resources etc...
session.setAttribute("customerConfig",customerConfig);
}
3.) в ваших классах POJO вы можете получить доступ к нему следующим образом
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
CustomerConfig cc =(CustomerConfig)attr.getRequest().getSession().getAttribute("customerConfig");
parameter = cc.getYourCustomerProperty();
4.) В ваших компонентах, сервисах и т. Д. Вы можете автоматически выполнить запрос, например:
@Component
@Scope("request")
public class FooBar {
@Autowired
private HttpServletRequest request;
public void function()
{ CustomerConfig config = request().getSession().getAttribute("customerConfig");
parameter = cc.getYourCustomerProperty();
//...
}
}
Комментарии:
1. Звучит здорово, спасибо. RequestContextHolder — это именно то, что мне нужно.