Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @可缓存不';t拦截该方法,缓存始终为空_Java_Spring_Spring Boot_Caching_Spring Cache - Fatal编程技术网

Java @可缓存不';t拦截该方法,缓存始终为空

Java @可缓存不';t拦截该方法,缓存始终为空,java,spring,spring-boot,caching,spring-cache,Java,Spring,Spring Boot,Caching,Spring Cache,我有一个方法如下: @Cacheable(value = "SAMPLE") public List<SomeObj> find() { // Method that initiates and returns the List<SomeObj> and takes around 2-3 seconds, does some logging too } 我的pom.xml文件中有以下内容: <!-- https://mvnrepository.com/a

我有一个方法如下:

@Cacheable(value = "SAMPLE")
public List<SomeObj> find() {
     // Method that initiates and returns the List<SomeObj> and takes around 2-3 seconds, does some logging too
}
我的
pom.xml文件中有以下内容:

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
    <version>1.5.14.RELEASE</version>
</dependency>
当我将一个
@Autowired
CacheManager
实例放入我的
@Service
中时,我可以看到存在一个名为
“SAMPLE”
的缓存,但它的条目总是空的。我一次又一次地调用方法
find()
,但它似乎没有填充缓存

我尝试将一个参数(比如
int a
)放入
find()
方法,并将其作为
key=“#a”
放入
@Cacheable
,但没有任何更改

当我试图在一个孤立的环境中重新创建问题时,我可以看到它工作正常。但当我添加依赖项(非开源公司库,其中也包括
EhCache
配置)时,它就不起作用了。我如何调试这个,我做错了什么

更新:

我还尝试在
@Cacheable
中使用
cacheManager=myCacheManager
。不走运

更新2:

我正在使用
AspectJ
和springaop。我认为这可能与此有关。我尝试了
@EnableCaching(mode=AdviceMode.ASPECTJ)
@enableloadtimewing
但都是一样的

更新3:

我终于能够重现这个问题,它是:


基本上,当您运行应用程序并在向其发送任何行后运行
telnet localhost 9000
时,即使在
CachedController
中调用该方法两次(第二次来自缓存),它也应该打印
NOT CACHED
。但它会打印两次。

请确保您正在将缓存设置到cachemanager中,如下所示

@EnableCaching
@Configuration
public SomeConf {   

    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("find():List<SomeObj>")));
        return cacheManager;
    }


}
@EnableCaching
@配置
公共文件{
@豆子
公共缓存管理器缓存管理器(){
SimpleCacheManager cacheManager=新的SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(新的ConcurrentMapCache(“find():List”));
返回缓存管理器;
}
}

正如Andrews S所指出的,这听起来确实像是自动配置中的碰撞缓存

有一些关于如何选择
cacheManager
的有用说明,特别是关于如何继续的想法。在这种情况下,您要做的是建立一个
cachingconfiguer
来选择您的缓存-也许您可以扩展
cachingconfiguresupport
(如下例)并完成

必须注册类型为
CacheManager
的bean,因为框架没有可以用作约定的合理默认值。而
元素假定一个名为“cacheManager”的bean,
@EnableCaching
则按类型搜索缓存管理器bean。因此,缓存管理器bean方法的命名并不重要

对于那些希望在
@EnableCaching
和要使用的确切缓存管理器bean之间建立更直接关系的人,可以实现
cachingconfiguer
回调接口。请注意下面的
@Override
-注释方法:

这种方法可能是可取的,因为它更显式,或者为了区分同一容器中存在的两个
CacheManager
bean,可能需要这种方法

还要注意上面示例中的
keyGenerator
方法。这允许根据Spring的
KeyGenerator
SPI定制缓存密钥生成策略。通常,
@EnableCaching
将为此配置Spring的
SimpleKeyGenerator
,但在实现
cachingconfiguer
时,必须明确提供密钥生成器。如果不需要自定义,则从此方法返回
null
新SimpleKeyGenerator()

CachingConfigurer
提供了额外的自定义选项:建议从
CachingConfigurerSupport
扩展,它为所有方法提供了默认实现,如果您不需要自定义所有内容,这些方法可能会很有用。有关更多详细信息,请参阅

您可能还发现此线程非常有用:

编辑:

谢天谢地,我有一个使用缓存的项目,并写了以下几点:

@Bean
@Override
public CacheResolver cacheResolver() {
    return new SimpleCacheResolver(cacheManager()) { 

        @Override
        protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
            Collection<String> toReturn = super.getCacheNames(context);
            toReturn.forEach(System.out::println);
            return toReturn;
        }

        @Override
        public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
            System.out.println(Arrays.toString(context.getArgs()));
            System.out.println(context.getClass());
            System.out.println(context.getMethod());
            System.out.println(context.getOperation());
            return super.resolveCaches(context);
        }
    };
}
@Bean
@凌驾
公共CacheResolver CacheResolver(){
返回新的SimpleCacheSolver(cacheManager()){
@凌驾
受保护的集合getCacheNames(CacheOperationInvocationContext上下文){
Collection toReturn=super.getCacheNames(上下文);
toReturn.forEach(System.out::println);
回归回归;
}
@凌驾

public Collection根本原因是您误用了“afterPropertiesSet”。因此,您所做的是无休止的循环,并且从未将控制权传递回Spring管道,因此Spring无法正确初始化缓存设施


查看修复问题的代码:

类路径上是否有一个ehcache.xml文件,它定义了一个名为“find():List”的缓存?谢谢你的评论。这里有两种情况:1)我没有显式地配置
CacheManager
,Spring配置了一个
GuavacheManager
,因此
ehcache.xml
是不相关的。2)当我用
EhCacheManager
显式地定义
CacheManager
@Bean
并放置一个ehcache.xml时定义一个名为“find():List”的缓存(实际上它不接受
@AndrewS您能想到更新问题的其他内容吗?谢谢。您能确认扫描了
SomeConf
吗?
find()
没有参数,因此不确定它将用于密钥-也许可以让Spring源代码查看是否实际调用了缓存代理类。@AndrewS我可以确认扫描了
@SomeConf
。我还尝试将一个参数(
int a
)放入
@EnableCaching
@Configuration
public SomeConf {   

    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("find():List<SomeObj>")));
        return cacheManager;
    }


}
@Configuration
@EnableCaching
public class AppConfig extends CachingConfigurerSupport {

     @Bean
     public MyService myService() {
         // configure and return a class having @Cacheable methods
         return new MyService();
     }

     @Bean
     @Override
     public CacheManager cacheManager() {
         // configure and return an implementation of Spring's CacheManager SPI
         SimpleCacheManager cacheManager = new SimpleCacheManager();
         cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
         return cacheManager;
     }

     @Bean
     @Override
     public KeyGenerator keyGenerator() {
         // configure and return an implementation of Spring's KeyGenerator SPI
         return new MyKeyGenerator();
     }
}
@Bean
@Override
public CacheResolver cacheResolver() {
    return new SimpleCacheResolver(cacheManager()) { 

        @Override
        protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
            Collection<String> toReturn = super.getCacheNames(context);
            toReturn.forEach(System.out::println);
            return toReturn;
        }

        @Override
        public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
            System.out.println(Arrays.toString(context.getArgs()));
            System.out.println(context.getClass());
            System.out.println(context.getMethod());
            System.out.println(context.getOperation());
            return super.resolveCaches(context);
        }
    };
}