[alibaba/easyexcel]ehcache的依赖有可能导致cacheManager被偷偷替换掉

2024-05-09 955 views
6

如题,我使用的是redis作为cachemanager,配置时,只用了RedisCacheConfiguration,所以加了easyexcel的依赖后,默认cacheManger就被偷偷替换了~ 谁能想到一个excel库会依赖一个cachemanager呢

回答

0

Spring Cache 的流程是这样的

导入spring boot cache 之后

触发CacheAutoConfiguration自动注入

自动注入会通过 CacheAutoConfiguration&CacheConfigurationImportSelector 类把所有的缓存配置器扫描进去

image

配置之后首先按照Condition来扫描配置 通过普通的Condition (比如 ConditionOnClass等等) 过滤一次 剩下一批

通用的CacheCondition会再过滤一次配置器 这一步会判断用户是否直接指定了缓存类型

image

如果用户选择了,那最后只会剩下一个CacheConfiguraion
如果用户没选择,会剩下一大堆CacheConfiguration 这一大堆都是符合要求的 然后按照枚举顺序依次执行
因为Jcache在Redis前面
当引入了easyexcel包的时候 会触发JcacheConfig进入扫描 所以CacheManger被替换成了Jcache

目前想解决只能在easyexcel里面把Jcache的SPI干掉,当然这个想法不太靠谱

推荐你 手动通过"spring.cache.type"配置 redis缓存

1

@gongxuanzhang 原理和解决方法我当然知道,但只是吐槽这么一个问题,你一个搞excel的库,依赖的cache怎么能偷偷替换用户的cache呢。解决方法应该是easyexcel不要配置使用默认的cachemanager,而是自己用注解配个不会干扰到用户的。

8

@gongxuanzhang 原理和解决方法我当然知道,但只是吐槽这么一个问题,你一个搞excel的库,依赖的cache怎么能偷偷替换用户的cache呢。解决方法应该是easyexcel不要配置使用默认的cachemanager,而是自己用注解配个不会干扰到用户的。

由于redisson和ehcache都实现了javax.cache.cacheManager,类型如果指定redis还是会启动报错找不到。 我的项目中同时引入了spring data redis、spring data cache、redisson、hibernate并开启了二级缓存,现在加入easyexcel以后,启动的时候发现javax.cache.cacheManager找不到,我经过反复调试找到两种解决方案: 第一种(推荐),在application.yml文件中配置指定的缓存类型:

spring:  
  cache:
    type: jcache
    jcache:
      provider: org.redisson.jcache.JCachingProvider

第二种方案(不建议,由于默认小于5M用内存,超过5M会使用EhCache,所以导入数据量不大时可以这么做,大批量数据导入时该方法不适用),pom.xml文件中排除ehcache的依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>${easyexcel.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>ehcache</artifactId>
            <groupId>org.ehcache</groupId>
        </exclusion>
    </exclusions>
</dependency>

如果有遇到该问题的朋友,希望能帮到大家!

### 同时,看看大佬们是否能够把缓存这块再抽象一层,具体实现由用户自己决定呢?比如日志框架slf4j作为抽象层,具体实现用户自己配置什么就用什么,建议仅作参考