thymeleaf 缓存
*********************
相关类与接口
ThymeleafAutoConfiguration:自动配置类
@Configuration(
proxyBeanMethods = false
)
@EnableConfigurationProperties({ThymeleafProperties.class})
@ConditionalOnClass({TemplateMode.class, SpringTemplateEngine.class})
@AutoConfigureAfter({WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class})
public class ThymeleafAutoConfiguration {
public ThymeleafAutoConfiguration() {
}
。。。
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnMissingBean(
name = {"defaultTemplateResolver"}
)
static class DefaultTemplateResolverConfiguration {
private static final Log logger = LogFactory.getLog(ThymeleafAutoConfiguration.DefaultTemplateResolverConfiguration.class);
private final ThymeleafProperties properties;
private final ApplicationContext applicationContext;
DefaultTemplateResolverConfiguration(ThymeleafProperties properties, ApplicationContext applicationContext) {
this.properties = properties;
this.applicationContext = applicationContext;
}
@PostConstruct
void checkTemplateLocationExists() {
boolean checkTemplateLocation = this.properties.isCheckTemplateLocation();
if (checkTemplateLocation) {
TemplateLocation location = new TemplateLocation(this.properties.getPrefix());
if (!location.exists(this.applicationContext)) {
logger.warn("Cannot find template location: " + location + " (please add some templates or check your Thymeleaf configuration)");
}
}
}
@Bean
SpringResourceTemplateResolver defaultTemplateResolver() {
//创建模板解析器
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(this.applicationContext);
resolver.setPrefix(this.properties.getPrefix());
resolver.setSuffix(this.properties.getSuffix());
resolver.setTemplateMode(this.properties.getMode());
if (this.properties.getEncoding() != null) {
resolver.setCharacterEncoding(this.properties.getEncoding().name());
}
resolver.setCacheable(this.properties.isCache());
Integer order = this.properties.getTemplateResolverOrder();
if (order != null) {
resolver.setOrder(order);
}
resolver.setCheckExistence(this.properties.isCheckTemplate());
return resolver;
}
}
}
ThymeleafProperties
@ConfigurationProperties(
prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
private boolean checkTemplate = true;
private boolean checkTemplateLocation = true;
private String prefix = "classpath:/templates/";
private String suffix = ".html";
private String mode = "HTML";
private Charset encoding;
private boolean cache;
private Integer templateResolverOrder;
private String[] viewNames;
private String[] excludedViewNames;
private boolean enableSpringElCompiler;
private boolean renderHiddenMarkersBeforeCheckboxes;
private boolean enabled;
private final ThymeleafProperties.Servlet servlet;
private final ThymeleafProperties.Reactive reactive;
public ThymeleafProperties() {
this.encoding = DEFAULT_ENCODING;
this.cache = true;
this.renderHiddenMarkersBeforeCheckboxes = false;
this.enabled = true; //缓存默认开启
this.servlet = new ThymeleafProperties.Servlet();
this.reactive = new ThymeleafProperties.Reactive();
}
SpringResourceTemplateResolver:模板解析器
public class SpringResourceTemplateResolver extends AbstractConfigurableTemplateResolver implements ApplicationContextAware {
private ApplicationContext applicationContext = null;
public SpringResourceTemplateResolver() {
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
return new SpringResourceTemplateResource(this.applicationContext, resourceName, characterEncoding);
}
}
AbstractConfigurableTemplateResolver
public abstract class AbstractConfigurableTemplateResolver extends AbstractTemplateResolver {
public static final TemplateMode DEFAULT_TEMPLATE_MODE;
public static final boolean DEFAULT_CACHEABLE = true;
public static final Long DEFAULT_CACHE_TTL_MS;
private String prefix = null;
private String suffix = null;
private boolean forceSuffix = false;
private String characterEncoding = null;
private TemplateMode templateMode;
private boolean forceTemplateMode;
private boolean cacheable;
private Long cacheTTLMs;
private final HashMap<String, String> templateAliases;
private final PatternSpec xmlTemplateModePatternSpec;
private final PatternSpec htmlTemplateModePatternSpec;
private final PatternSpec textTemplateModePatternSpec;
private final PatternSpec javaScriptTemplateModePatternSpec;
private final PatternSpec cssTemplateModePatternSpec;
private final PatternSpec rawTemplateModePatternSpec;
private final PatternSpec cacheablePatternSpec;
private final PatternSpec nonCacheablePatternSpec;
public AbstractConfigurableTemplateResolver() {
this.templateMode = DEFAULT_TEMPLATE_MODE;
this.forceTemplateMode = false;
this.cacheable = true;
this.cacheTTLMs = DEFAULT_CACHE_TTL_MS;
this.templateAliases = new HashMap(8);
this.xmlTemplateModePatternSpec = new PatternSpec();
this.htmlTemplateModePatternSpec = new PatternSpec();
this.textTemplateModePatternSpec = new PatternSpec();
this.javaScriptTemplateModePatternSpec = new PatternSpec();
this.cssTemplateModePatternSpec = new PatternSpec();
this.rawTemplateModePatternSpec = new PatternSpec();
this.cacheablePatternSpec = new PatternSpec(); //缓存路径
this.nonCacheablePatternSpec = new PatternSpec();
}
StandardCacheManager:缓存配置
public class StandardCacheManager extends AbstractCacheManager {
public static final String DEFAULT_TEMPLATE_CACHE_NAME = "TEMPLATE_CACHE";
public static final int DEFAULT_TEMPLATE_CACHE_INITIAL_SIZE = 20;
public static final int DEFAULT_TEMPLATE_CACHE_MAX_SIZE = 200;
public static final boolean DEFAULT_TEMPLATE_CACHE_ENABLE_COUNTERS = false;
public static final boolean DEFAULT_TEMPLATE_CACHE_USE_SOFT_REFERENCES = true;
public static final String DEFAULT_TEMPLATE_CACHE_LOGGER_NAME = null;
public static final ICacheEntryValidityChecker<TemplateCacheKey, TemplateModel> DEFAULT_TEMPLATE_CACHE_VALIDITY_CHECKER = new StandardParsedTemplateEntryValidator();
public static final String DEFAULT_EXPRESSION_CACHE_NAME = "EXPRESSION_CACHE";
public static final int DEFAULT_EXPRESSION_CACHE_INITIAL_SIZE = 100;
public static final int DEFAULT_EXPRESSION_CACHE_MAX_SIZE = 500;
public static final boolean DEFAULT_EXPRESSION_CACHE_ENABLE_COUNTERS = false;
public static final boolean DEFAULT_EXPRESSION_CACHE_USE_SOFT_REFERENCES = true;
public static final String DEFAULT_EXPRESSION_CACHE_LOGGER_NAME = null;
public static final ICacheEntryValidityChecker<ExpressionCacheKey, Object> DEFAULT_EXPRESSION_CACHE_VALIDITY_CHECKER = null;
private String templateCacheName = "TEMPLATE_CACHE";
private int templateCacheInitialSize = 20;
private int templateCacheMaxSize = 200; //最大缓存个数
private boolean templateCacheEnableCounters = false;
private boolean templateCacheUseSoftReferences = true;
private String templateCacheLoggerName;
private ICacheEntryValidityChecker<TemplateCacheKey, TemplateModel> templateCacheValidityChecker;
private String expressionCacheName;
private int expressionCacheInitialSize;
private int expressionCacheMaxSize;
private boolean expressionCacheEnableCounters;
private boolean expressionCacheUseSoftReferences;
private String expressionCacheLoggerName;
private ICacheEntryValidityChecker<ExpressionCacheKey, Object> expressionCacheValidityChecker;
public StandardCacheManager() {
this.templateCacheLoggerName = DEFAULT_TEMPLATE_CACHE_LOGGER_NAME;
this.templateCacheValidityChecker = DEFAULT_TEMPLATE_CACHE_VALIDITY_CHECKER;
this.expressionCacheName = "EXPRESSION_CACHE";
this.expressionCacheInitialSize = 100;
this.expressionCacheMaxSize = 500;
this.expressionCacheEnableCounters = false;
this.expressionCacheUseSoftReferences = true;
this.expressionCacheLoggerName = DEFAULT_EXPRESSION_CACHE_LOGGER_NAME;
this.expressionCacheValidityChecker = DEFAULT_EXPRESSION_CACHE_VALIDITY_CHECKER;
}
*********************
开启缓存
application.properties:缓存默认开启
logging.level.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=trace
执行引擎模板,相关日志输出:
[THYMELEAF][http-nio-8080-exec-1][TEMPLATE_CACHE][CACHE_MISS] Cache miss in cache "TEMPLATE_CACHE" for key "index3".
//首次请求的时候,没有缓存
2020-08-12 18:04:55.286 TRACE 19272 --- [nio-8080-exec-1] o.t.TemplateEngine.cache.TEMPLATE_CACHE : [THYMELEAF][http-nio-8080-exec-1][TEMPLATE_CACHE][CACHE_ADD][1] Adding cache entry in cache "TEMPLATE_CACHE" for key "index3". New size is 1.
//将数据添加进缓存
2020-08-12 18:04:56.795 TRACE 19272 --- [nio-8080-exec-2] o.t.TemplateEngine.cache.TEMPLATE_CACHE : [THYMELEAF][http-nio-8080-exec-2][TEMPLATE_CACHE][CACHE_HIT] Cache hit in cache "TEMPLATE_CACHE" for key "index3".
//再次请求时缓存命中
*********************
关闭缓存
application.properties
spring.thymeleaf.cache=false
logging.level.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=trace
执行模板引擎,相关日志输出
[THYMELEAF][CACHE_INITIALIZE] Initializing cache TEMPLATE_CACHE. Max size: 200. Soft references are used.
2020-08-12 18:14:11.975 TRACE 19016 --- [nio-8080-exec-2] o.t.TemplateEngine.cache.TEMPLATE_CACHE : [THYMELEAF][http-nio-8080-exec-2][TEMPLATE_CACHE][CACHE_MISS] Cache miss in cache "TEMPLATE_CACHE" for key "index3".
2020-08-12 18:14:19.520 TRACE 19016 --- [nio-8080-exec-3] o.t.TemplateEngine.cache.TEMPLATE_CACHE : [THYMELEAF][http-nio-8080-exec-3][TEMPLATE_CACHE][CACHE_MISS] Cache miss in cache "TEMPLATE_CACHE" for key "index3".
由于关闭了缓存,两次请求均为 CACHE_MISS
版权声明:本文为weixin_43931625原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。