mustache注入helper以及热加载问题解决

来源:互联网 发布:免押金网络兼职 编辑:程序博客网 时间:2024/06/05 17:18
最近项目选用了mustache来代替velocity,由前端来完成所有的mustache模板的开发,后台只关注后端java代码的开发。
用的是spring mvc,模板解析的类用的是mustache自己开发的handlebars的类
自已定义了一些helper方法, 
<bean id="viewResolver"
class="com.github.jknack.handlebars.springmvc.HandlebarsViewResolver">
<property name="prefix" value="/WEB-INF/hbs" />
<property name="suffix" value=".hbs" />
<property name="helpers">
<map>
<entry key="imageURIBroker">
<bean class="com.taotaosou.tts.helper.ImageURIBrokerHelper" />
</entry>
<entry key="assign">
<bean class="com.taotaosou.tts.helper.AssignHelper" />
</entry>
<entry key="json">
<bean class="com.taotaosou.tts.helper.Jackson2Helper" />
</entry>
    ...
</map>
</property>
</bean>
出现了个怪异的问题,用run启动时会报
严重: StandardWrapper.Throwable
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'viewResolver' defined in class path resource [spring/mvc-context.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No helper method was found in: java.util.LinkedHashMap
Debug时则不会这个错。
解决办法:
看了一下HandlebarsViewResolver的代码里有两个setHelper的注入方法
  public void setHelpers(final Map<String, Helper<?>> helpers) {
    notNull(helpers, "The helpers are required.");
    this.helpers.putAll(helpers);
  }
 
  public void setHelpers(final List<Object> helpers) {
    notNull(helpers, "The helpers are required.");
    this.helperSources.addAll(helpers);
  }
Run和Debug时分别会调用两个不同的方法,用helperSource去注册helper就会报错。
直接将第二个setHelpers重命名,并且springMVC里引用新改后的类,解决了这个问题。
<bean id="viewResolver" class="com.taotaosou.tts.mvc.HandlebarsViewResolver">
另外mustache里面, 模板改了需重启才能生效,也把mustache的缓存给关了,还是没用,发现是
spring mvc解析器里AbstractCachingViewResolver自带的cache的问题。
没有找到地方关,直接在子类HandlebarsViewResolver里关了,并打开mustache自带的cache
  protected Handlebars createHandlebars(final URLTemplateLoader templateLoader) {
    return new Handlebars(templateLoader);
  }
改为
protected Handlebars createHandlebars(final URLTemplateLoader templateLoader) {
        super.setCache(false);
        return new Handlebars(templateLoader).with(new ConcurrentMapTemplateCache());
}