通过实现Spring的ThemeSource类,使用hibernate的Spring主题

时间:2011-09-26 19:07:27

标签: java hibernate spring themes

有谁知道如何在春天使用自定义ThemeSource?我已经看到很多关于如何使用ResourceBundleThemeSource将属性文件与主题文件一起使用的示例。然而,我没有看到如何使用hibernate来存储vairous属性(例如单个css属性),使用自定义ThemeSource读取属性并且仍然能够在jsp中使用spring主题标签。

我知道我可以创建一个控制器并使用hibernate从数据库中获取这些属性,但我更感兴趣的是知道如何使用Spring的ThemeSource实现。

如果有人有任何想法或例子,我会很感激。

由于

2 个答案:

答案 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); } } 查找快速访问主题元素。我们已经使用了一段时间,它对我们来说非常好。