有谁知道如何在春天使用自定义ThemeSource?我已经看到很多关于如何使用ResourceBundleThemeSource将属性文件与主题文件一起使用的示例。然而,我没有看到如何使用hibernate来存储vairous属性(例如单个css属性),使用自定义ThemeSource读取属性并且仍然能够在jsp中使用spring主题标签。
我知道我可以创建一个控制器并使用hibernate从数据库中获取这些属性,但我更感兴趣的是知道如何使用Spring的ThemeSource实现。
如果有人有任何想法或例子,我会很感激。
由于
答案 0 :(得分:2)
要在Web应用程序中使用主题,必须设置org.springframework.ui.context.ThemeSource
接口的实现。要使用自定义ThemeSource实现,您可以在应用程序上下文中使用保留名称themeSource
注册bean。 Web应用程序上下文自动检测具有该名称的bean并使用它。
以下是ThemeSource
界面:
package org.springframework.ui.context;
public interface ThemeSource {
Theme getTheme(String themeName);
}
这里唯一的黑马是Theme
类型,实际上只不过是:
package org.springframework.ui.context;
public interface Theme {
String getName();
MessageSource getMessageSource();
}
事实上,从Spring =>中已经有Theme
类型的便利实现。 SimpleTheme
请注意,ThemeSource 期望一个Spring的MessageSource,这意味着在您的情况下,存储在数据库中的主题属性需要“转换”才能与MessageSource
界面。
您可以自己编写DatabaseDrivenMessageSource
,也可以从here
现在,拥有所有这些变量,这里是一个自定义DatabaseThemeSource
(将成为themeSource
bean):
public class DatabaseThemeSource implements ThemeSource {
private YourThemeDao themeDao;
public Theme getTheme( String themeName ) {
if (themeName == null) { return null; }
MessageSource messageSource = new DatabaseDrivenMessageSource( themeDao );
theme = new SimpleTheme( themeName, messageSource );
return theme;
}
// init your themeDao
}
答案 1 :(得分:1)
tolitius提供的答案可以正常使用,但对于实际使用,我认为您需要加入某种缓存。
对您网站的每个请求都需要您的主题,但是您是否希望每个请求只是为了查找某些颜色而访问您的数据库?主题通常不是很大,不经常变化。所以他们是加载到内存中并保存在那里的好人选。这就是我们对运行的网站所做的事情,我们在内存中保留了大约50个主题,这些主题是在启动时从Hibernate加载的。它可以非常快速地提供主题请求。
核心类当然是你的DatabaseThemeSource
bean,它实现了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会话和LazyLoadingExceptions等问题。它也更有效,因为您可以构造必要的{ {1}}对象只需一次,而不必在每个请求上执行此操作:
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);
}
}
查找快速访问主题元素。我们已经使用了一段时间,它对我们来说非常好。