前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nested exception is java.lang.IllegalStateException: refreshAfterWrite requires

nested exception is java.lang.IllegalStateException: refreshAfterWrite requires

原创
作者头像
谙忆
修改2020-08-10 10:17:08
1.8K0
修改2020-08-10 10:17:08
举报
文章被收录于专栏:程序编程之旅程序编程之旅

已解决 nested exception is java.lang.IllegalStateException: refreshAfterWrite requires a LoadingCache异常解决

问题描述:

SpringBoot项目使用Caffeine缓存,出现如下异常信息:

代码语言:txt
复制
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cache' defined in class path resource [com/copyfuture/web/copyfutureweb/configurer/CacheConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.github.benmanes.caffeine.cache.Cache]: Factory method 'cache' threw exception; nested exception is java.lang.IllegalStateException: refreshAfterWrite requires a LoadingCache
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:607)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1305)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1144)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
	... 24 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.github.benmanes.caffeine.cache.Cache]: Factory method 'cache' threw exception; nested exception is java.lang.IllegalStateException: refreshAfterWrite requires a LoadingCache
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622)
	... 42 more
Caused by: java.lang.IllegalStateException: refreshAfterWrite requires a LoadingCache
	at com.github.benmanes.caffeine.cache.Caffeine.requireState(Caffeine.java:194)
	at com.github.benmanes.caffeine.cache.Caffeine.requireNonLoadingCache(Caffeine.java:1015)
	at com.github.benmanes.caffeine.cache.Caffeine.build(Caffeine.java:921)
	at com.copyfuture.web.copyfutureweb.configurer.CacheConfig.cache(CacheConfig.java:58)
	at com.copyfuture.web.copyfutureweb.configurer.CacheConfig$$EnhancerBySpringCGLIB$$600e6612.CGLIB$cache$0(<generated>)
	at com.copyfuture.web.copyfutureweb.configurer.CacheConfig$$EnhancerBySpringCGLIB$$600e6612$$FastClassBySpringCGLIB$$ac98c0d2.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
	at com.copyfuture.web.copyfutureweb.configurer.CacheConfig$$EnhancerBySpringCGLIB$$600e6612.cache(<generated>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 43 more

关键信息:

代码语言:txt
复制
Factory method 'cache' threw exception; nested exception is java.lang.IllegalStateException: refreshAfterWrite requires a LoadingCache  

原因

因为我使用的是refreshAfterWrite配置。

必须指定一个CacheLoader。不用该配置则无需这个bean,如上所述,该CacheLoader将关联被该缓存管理器管理的所有缓存,所以必须定义为CacheLoader<Object, Object>,自动配置将忽略所有泛型类型。

解决方案

  1. 在构建LoadingCache对象的时候 build()方法中指定过期之后的加载策略方法

代码:

代码语言:txt
复制
public class CacheConfig {


    /**
     * 相当于在构建LoadingCache对象的时候 build()方法中指定过期之后的加载策略方法
     * 必须要指定这个Bean,refreshAfterWrite=60s属性才生效
     * @return
     */
    @Bean
    public CacheLoader<String, Object> cacheLoader() {
        CacheLoader<String, Object> cacheLoader = new CacheLoader<String, Object>() {
            @Override
            public Object load(String key) throws Exception {
                return null;
            }
            // 重写这个方法将oldValue值返回回去,进而刷新缓存
            @Override
            public Object reload(String key, Object oldValue) throws Exception {
                return oldValue;
            }
        };
        return cacheLoader;
    }

    @Bean
    public Cache<String, Object> cache(CacheLoader<String, Object> cacheLoader) {
        return Caffeine.newBuilder()
                // 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存 最后一次写入后经过固定时间过期
                .refreshAfterWrite(3600L, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(100)
                // 缓存的最大条数
                .maximumSize(100000)
                //软引用
                .softValues()
                .build(cacheLoader);
    }
}

其中CacheLoader必须要有,在cache方法中进行指定过期之后的加载策略方式,也就是build(cacheLoader)。

作者:谙忆

地址:https://chenhx.blog.csdn.net/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原因
  • 解决方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档