Ответ, который дает Толиций, будет работать нормально, но для реального использования я думаю, что вам нужно включить какое-то кэширование.
Каждый запрос на ваш сайт будет нуждаться в вашей теме, но хотите ли вы, чтобы каждый запрос попадал в вашу базу данных, просто чтобы посмотреть некоторые цвета? Темы обычно не очень большие и меняются не очень часто. Таким образом, они являются хорошим кандидатом для загрузки в память и хранения их там. Это то, что мы делаем с сайтом, который мы запускаем, мы храним около 50 тем в памяти, которые загружаются из Hibernate при запуске. Это делает обслуживание запросов к теме очень быстрым.
Основной класс - это, конечно, ваш компонент DatabaseThemeSource
, который реализует ThemeSource
. Если у вас есть доступная библиотека кеша, такая как Ehcache, вы можете использовать ее, но у большинства людей довольно мало тем, и для этого кеша подойдет простой Map
. Мы используем что-то вроде этого:
@Component("themeSource")
public class DatabaseThemeSource implements ThemeSource {
@Autowired
ThemeDAO themeDAO;
private final Map<String, Theme> themeCache;
public DatabaseThemeSource() {
themeCache = new HashMap<String, Theme>();
}
/**
* @see org.springframework.ui.context.ThemeSource#getTheme(java.lang.String)
*/
@Override
public Theme getTheme(String themeName) {
if (themeName == null) {
return null;
}
Theme theme = themeCache.get(themeName);
if (theme == null) {
Theme theme = themeDAO.getTheme(themeName);
if (theme != null) {
MessageSource messageSource = new ThemeMessageSource(theme);
theme = new SimpleTheme(themeName, messageSource);
synchronized (this.themeCache) {
themeCache.put(themeName, theme);
}
}
}
return theme;
}
/**
* Clears the cache of themes. This should be called whenever the theme is updated in the database.
*/
public void clearCache() {
synchronized (this.themeCache) {
themeCache.clear();
}
}
}
Затем вам нужно реализовать MessageSource
, который содержит все отдельные компоненты вашей темы. Стоит скопировать отдельные элементы вашей темы из объекта Hibernate в выделенный MessageSource
, чтобы у вас не возникало проблем с закрытыми сеансами Hibernate, исключениями LazyLoadingException и т. Д. Это также более эффективно, поскольку вы можете создать необходимый MessageFormat
объекты только один раз вместо того, чтобы делать это при каждом запросе:
public class ThemeMessageSource extends AbstractMessageSource {
private final Map<String, MessageFormat> messages;
public ThemeMessageSource(Theme theme) {
messages = new HashMap<String, MessageFormat>();
messages.put("heading1", createMessageFormat(theme.getHeading1(), null));
messages.put("heading2", createMessageFormat(theme.getHeading2(), null));
messages.put("colour1", createMessageFormat(theme.getColour1(), null));
messages.put("colour2", createMessageFormat(theme.getColour2(), null));
}
public ThemeMessageSource(Map<String, MessageFormat> messages) {
this.messages = messages;
}
@Override
protected MessageFormat resolveCode(String code, Locale locale) {
return messages.get(code);
}
}
Конечным результатом является то, что это быстро. Все ваши темы хранятся в памяти, и к элементам тем можно быстро получить доступ посредством простого поиска Map
. Мы использовали это некоторое время, и это очень хорошо работает для нас.