在可缓存方法类cast异常中调用spring可缓存方法

hgc7kmma  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(416)

我正在尝试使用spring cacheable,但是得到一个类强制转换异常

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CacheableTest.class, loader = AnnotationConfigContextLoader.class)
@Configuration
@EnableCaching
public class CacheableTest {
    public static final String CACHE = "cache";

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager(CACHE);
    }

    @Autowired
    DataService service;

    @Test
    public void cacheTest() {
        final String name = "name";
        Data a = service.getData(name);
        Data b = service.getData(new String(name));
        Assert.assertSame(a, b);
        String c = service.getValue(service.getData(name));
        String d = service.getValue(service.getData(new String(name)));
        Assert.assertSame(c, d);
        String e = service.getValue(name);
        String f = service.getValue(new String(name));
        Assert.assertSame(e, f);
    }

    public static class Data {
        private String value;
        public Data(String value) {
            this.value = value;
        }
    }

    @Service
    public static class DataService {
        @Resource
        private DataService self;

        @Cacheable(CACHE)
        public Data getData(String name) {
            return new Data(name);
        }

        @Cacheable(CACHE)
        public String getValue(Data data) {
            return data.value;
        }

        @Cacheable(CACHE)
        public String getValue(String name) {
            return self.getData(name).value;
        }
    }

}

特例说 CacheableTest$Data cannot be cast to java.lang.String 在字符串e处发生。我们知道为什么吗?

icnyk63a

icnyk63a1#

您声明了两个参数相同但返回类型不同的方法:

public Data getData(String name)
public String getValue(String name)

你把他们都标记为 @Cacheable 具有相同的缓存名称 CACHE . 因此,您将共享一个缓存以存储两个方法的结果。两种方法的参数完全相同( String )所以缓存spring计算的两个 Data 以及 Value 会发生碰撞。
调用的第一个方法将返回spring将放入缓存的结果,第二个方法将尝试从缓存中检索相同的结果(因为缓存名称和方法参数匹配),并尝试将其转换为其他类型-因此,类转换异常。
这和你这样做差不多:

Map<String, Object> cache = new HashMap<>();
cache.put("key", "value1");
int i = (Integer)cache.get("key")

相关问题