大数据平台技术笔记

Spring Cache的一次问题解决过程

2022-06-14  本文已影响0人  OkGogogooo

1. 环境

2. 背景

  想在项目中引入Spring Cache,原先是自己定义注解,利用AOP实现的对方法返回结果的缓存。现在想基于SpringCache重写这些注解。

... 省略更多
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <version>2.4.4</version>
        </dependency>
... 省略更多
# cache
spring.cache.type=jcache
spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider
spring.cache.jcache.config=classpath:/ehcache.xml
...省略更多
@EnableCaching
public class MainApplication
{   
...
}

启动程序的时候,报如下错误:


image.png

3. 补充说明

  在《Spring官方文档》中有说明,Ehcache3.x已经完全实现了JSR规范,可以以JCache的方式引入Ehcache。而Spring-context-support-5.3.5.jar中的EhCacheCacheManager使用的是"net.sf.ehcache.CacheManager",这是EhCache 2.x的。

image.png
  另外的,程序使用的是application.properties配置文件进行配置。Ehchahe及其他Cache在其中该如何配置,格式是怎样的,可以参考“org.springframework.boot.autoconfigure.cache.CacheProperties”这个类。
image.png

4.问题排查分析

在排查问题之前,首先需要大概了解一下Spring Cache的逻辑过程和主要类。其相关资料可以自行百度(可以参考:https://blog.csdn.net/xing_hung/article/details/122753476)。要理解这个过程,关键是理解CacheAutoConfiguration的CacheConfigurationImportSelector,从字面理解就可以知道,其主要功能是“导入”和“选择”。

image.png

另外一个是CacheConfigurations。


image.png

4.1 明确问题

  从前面的异常消息可以知道,问题是没有找到与jcache对应的CacheManager。现在需要找到CacheManager没有按照配置要求自动构建出来的原因。在JCacheCacheConfiguration中有构建和注册CacheManager的方法,为什么没有调用?


image.png

4.2 方法

JCacheCacheConfiguration这个类上面有很多的注解,特别是@ConditionXXX注解,我们知道它是起条件判定作用的,只有当条件满足时,这个Configuration类里面的@Bean注解才可能起作用。
理解一下注解:

// 这是一个起配置作用的类
@Configuration(proxyBeanMethods = false)
// 当Caching.class和JCacheCacheManager.class这几个类在类路径上,能被ClassLoader找到时此类才起作用。
@ConditionalOnClass({ Caching.class, JCacheCacheManager.class })
// 当找不到CacheManager类型的Bean时此类才起作用
@ConditionalOnMissingBean(org.springframework.cache.CacheManager.class)
// CacheCondition和JCacheAvailableCondition条件成立
@Conditional({ CacheCondition.class, JCacheCacheConfiguration.JCacheAvailableCondition.class })
@Import(HazelcastJCacheCustomizationConfiguration.class)
class JCacheCacheConfiguration implements BeanClassLoaderAware {
... 省略更多
}

这其中有些条件笔者也不能拿捏的准是不是成立,只能借助调试,进一步判定。

5. 解决办法

在pom.xml中引入javax.cache,问题得到解决。

        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
        </dependency>

6. 事后总结。

这个问题其实应该可以更早的就想到。因为从官方文档


image.png

或者是application.properties


image.png
都可以看到“JSR-107”。JSR,是Java Specification Requests的缩写,意思是Java规范提案,是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。它很可能是没有纳入到JDK中的,需要另外下载相应的javax包。
上一篇下一篇

猜你喜欢

热点阅读