java Freemarker获取原始模板对象
我用的是Spring Boot和Freemarker。我正在使用自定义加载程序从db加载模板:
public class ContentDbLoader implements TemplateLoader {
@Inject
private TemplateRepository templateRepository;
@Override
public void closeTemplateSource(Object templateSource) throws IOException {
return;
}
@Override
public Object findTemplateSource(String name) throws IOException {
return getTemplateFromName(name);
}
@Override
public long getLastModified(Object templateSource) {
MyTemplate template = (MyTemplate) templateSource;
template = templateRepository.findOne(template.getId());
return template.getLastModifiedDate().toEpochMilli();
}
@Override
public Reader getReader(Object templateSource, String encoding) throws IOException {
return new StringReader(((Template) templateSource).getContent());
}
private MyTemplate getTemplateFromName(String name) {
//my logic
}
}
我的模型是:
Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "channel", "communicationType", "country_id" }) })
public class Template extends AbstractEntity {
private static final long serialVersionUID = 8405971325717828643L;
@NotNull
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private Channel channel;
@NotNull
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private CommunicationType communicationType;
@Size(max = 255)
private String subject;
@NotNull
@Column(nullable = false)
@Lob
private String content;
@NotNull
@Column(nullable = false)
private String sender;
@NotNull
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Country country;
如您所见,我返回了一个来自db的MyTemplate对象。当我获得自定义模板来处理文本时,我会这样做:
contentFreemarkerConfig.getTemplate(CommunicationType.WALLET_BALANCE_THRESHOLD + "|" + Channel.EMAIL, locale)
但是这一行返回一个freemarker.template.Template
。我想让我的原始模板,以避免作出另一个查询数据库获得它回来
用Freemarker可以吗
# 1 楼答案
如果我理解的很好的话,您在这里尝试做的是让FreeMarker为您缓存应用程序域对象。这不是标准模板加载/缓存机制的设计初衷;模板库是一个较低级别的层,只处理其FreeMarker
Template
-s。由于每个域对象需要多个Template
-s,因此甚至不能将其与Template.customAttributes
和一个自定义TemplateConfigurerFactory
(可用于基于templateSource
将任意对象附加到Template
-s)连接在一起。所以,我认为你应该做的是:使用任何专用的缓存解决方案来缓存域对象。域对象可以直接存储
Template
对象(在您的案例中有多个)。在为缓存未命中创建域对象时,只需使用Template
构造函数创建那些Template
对象。因此,对于那些Template
-s FreeMarker的TemplateLoader
和缓存不被使用。只要它们不需要彼此#include
或#import
(因此FreeMarker需要能够获得它们),就可以了对于上述模板需要
#include
或#import
的模板(即通用实用程序模板),请设置TemplateLoader
并使用FreeMarker的缓存。因为这些只是模板,而不是一些应用程序域对象,所以您当然不需要做任何棘手的事情。(此外,这样的模板通常存储在类路径资源或配置目录中,所以您甚至不需要DatabaseTemplateLoader
。)