spring.cache 随笔1 CompositeCacheManager

0. "如果内心光明,那society也会是光明的"这话感觉很没有意义

先说回缘起(最近会有意无意的留意话题最初的起因):

  1. 在使用某框架的级联缓存(jvm缓存+分布式缓存)的时候,猜想是通过spring的应用事件监听机制实现的,感觉复杂度有点高。
  2. 后面有空的时候,看了下源码,发现其实是维护了多个CacheManager
  3. 一开始觉得奇怪,会怀疑人生:多个CacheManager有意义嘛?
  4. 这还没完,一番查找后,发现spring.cache早已提供了CompositeCacheManager,很好的通过1个CacheManager解决了问题,并且复杂度很低!(味道很不错,孩子很喜欢)

CompositeManager 可以认为是 代理+迭代器 组合的设计模式的一次很好的实践

Spring 中组合模式的运用举例

1. 先从外观上打摩

@Configuration
@ConditionalOnClass(DemoRedissonConfiguration.class)
@DependsOn(value = "demoRedissonConfiguration")
@EnableCaching
public class DemoCacheConfiguration extends CachingConfigurerSupport {
    private RedissonClient redissonClient;

    @Autowired(required = false)
    public void setRedissonClient(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

	// 就是这么容易构造
    @Override
    public CacheManager cacheManager() {
        return new CompositeCacheManager(localCacheManager(), distributedCacheManager());
    }

	// 分布式缓存
    private CacheManager distributedCacheManager() {
        Map<String, CacheConfig> config = Maps.newHashMap();
        Arrays.stream(CacheEnum.values()).filter(Objects::nonNull).forEach(var -> {
            String cacheName = var.getName();
            DemoCacheConfig cacheConfig = var.getConfig();
            CacheConfig redissonCacheConfig = new CacheConfig(cacheConfig.getExpireInSec(), cacheConfig.getExpireInSec());
            config.put(cacheName, redissonCacheConfig);
        });
        return new RedissonSpringCacheManager(this.redissonClient, config);
    }

	// JVM缓存
    private CacheManager localCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        List<CaffeineCache> caches = Arrays.stream(CacheEnum.values()).filter(Objects::nonNull).map(var -> {
            String cacheName = var.getName();
            DemoCacheConfig cacheConfig = var.getConfig();
            return new CaffeineCache(cacheName,
                    Caffeine
                            .newBuilder()
                            .initialCapacity(cacheConfig.getInitialCapacity())
                            .maximumSize(cacheConfig.getMaximumSize())
                            .expireAfterWrite(cacheConfig.getExpireInSec(), TimeUnit.SECONDS)
                            .build());
        }).collect(Collectors.toList());
        cacheManager.setCaches(caches);
        return cacheManager;
    }
}

2. 再看一下内部结构

简单的简单、扼要

package org.springframework.cache.support;

public class CompositeCacheManager implements CacheManager, InitializingBean {

	private final List<CacheManager> cacheManagers = new ArrayList<>();

	private boolean fallbackToNoOpCache = false;


	/**
	 * Construct an empty CompositeCacheManager, with delegate CacheManagers to
	 * be added via the {@link #setCacheManagers "cacheManagers"} property.
	 */
	public CompositeCacheManager() {
	}

	/**
	 * Construct a CompositeCacheManager from the given delegate CacheManagers.
	 * @param cacheManagers the CacheManagers to delegate to
	 */
	public CompositeCacheManager(CacheManager... cacheManagers) {
		setCacheManagers(Arrays.asList(cacheManagers));
	}


	/**
	 * Specify the CacheManagers to delegate to.
	 */
	public void setCacheManagers(Collection<CacheManager> cacheManagers) {
		this.cacheManagers.addAll(cacheManagers);
	}

	/**
	 * Indicate whether a {@link NoOpCacheManager} should be added at the end of the delegate list.
	 * In this case, any {@code getCache} requests not handled by the configured CacheManagers will
	 * be automatically handled by the {@link NoOpCacheManager} (and hence never return {@code null}).
	 */
	public void setFallbackToNoOpCache(boolean fallbackToNoOpCache) {
		this.fallbackToNoOpCache = fallbackToNoOpCache;
	}

	@Override
	public void afterPropertiesSet() {
		if (this.fallbackToNoOpCache) {
			this.cacheManagers.add(new NoOpCacheManager());
		}
	}


	@Override
	@Nullable
	public Cache getCache(String name) {
		for (CacheManager cacheManager : this.cacheManagers) {
			Cache cache = cacheManager.getCache(name);
			if (cache != null) {
				return cache;
			}
		}
		return null;
	}

	@Override
	public Collection<String> getCacheNames() {
		Set<String> names = new LinkedHashSet<>();
		for (CacheManager manager : this.cacheManagers) {
			names.addAll(manager.getCacheNames());
		}
		return Collections.unmodifiableSet(names);
	}

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: spring.thymeleaf.cache是一个Spring Thymeleaf模板引擎的配置属性,用于指定是否启用模板缓存。当该属性设置为true时,Thymeleaf会将解析过的模板缓存起来,以提高性能。如果该属性设置为false,则每次请求都会重新解析模板。默认情况下,该属性的值为true。 ### 回答2: Spring Thymeleaf Cache是Thymeleaf模板引擎在Spring框架中的缓存机制,用于提高网站的性能和响应速度。本质上,它是一个对Thymeleaf模板进行缓存处理的机制,在Spring框架中封装了对缓存的管理和清理。 在使用Spring Thymeleaf Cache时,可以设置缓存时间、缓存大小、缓存对象等,以便根据具体的应用场景进行优化。当使用缓存机制时,模板不需要在每次请求时重新编译和渲染,而是直接从缓存中读取,从而提高了网站的性能和响应速度。 Spring Thymeleaf Cache不仅可以缓存整个模板,还可以缓存模板中的某些区块,以满足更细粒度的缓存需求。此外,它还支持缓存模板层次结构,从而可以在自定义标记库、模板布局、片段等方面实现高效的缓存。 需要注意的是,如果没有正确配置和管理缓存,会导致内存泄漏、缓存过期导致数据不一致等问题,因此需要根据具体的应用场景进行性能测试和调优。 总之,Spring Thymeleaf Cache是一个强大而灵活的缓存机制,可以有效地提高网站的性能和响应速度。在使用时需要结合具体的应用场景进行灵活配置和管理,才能发挥出其最大的优势。 ### 回答3: spring.thymeleaf.cacheSpring Boot中Thymeleaf模板引擎的一个配置项。Thymeleaf是一款优秀的模板引擎,使用它可以方便地将数据呈现到HTML页面中,它支持各种功能强大的语法,包括表达式、条件语句、迭代操作、模板继承等等。 而spring.thymeleaf.cache属性,是控制应用是否对模板进行缓存的配置项。其默认值为true,表示应用会对模板进行缓存,这样可以提高应用的响应速度和性能。缓存的模板将在静态的地方进行保存,并且在需要的时候进行调用。当模板发生改变时,应用会自动刷新缓存。 但是,有时候我们可能需要在开发环境时关闭模板缓存,这是因为我们可能会频繁地对模板进行修改,这时候我们需要及时看到修改的结果,而不是等待缓存被自动刷新。此时可以将spring.thymeleaf.cache属性配置为false即可关闭缓存功能。 在生产环境中,一般建议开启缓存功能,以提高应用的运行效率和性能。如果应用的访问量较小,可以适当降低缓存时间,避免缓存时间过长而导致数据不够及时。在高访问量的应用中,可以考虑将缓存时间设置得更长一些,以提高应用的响应速度和性能。 总之,spring.thymeleaf.cache属性是一个非常实用的配置项,通过正确地配置该属性,我们可以在不同的环境中优化应用的运行效率和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肯尼思布赖恩埃德蒙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值