@CachePut在预配置缓存的@Configuration中不起作用

时间:2016-09-21 00:47:46

标签: spring caching

我试图在spring boot 1.3.5中使用spring stater-cache,除了@Configuration类中的预加载缓存外,一切正常。

Failed tests:
  CacheTest.testCacheFromConfig: expected:<n[eal]> but was:<n[ot cached]>

请看下面的代码,如果您之前遇到过这个问题,请与我分享:)

@Component
public class CacheObject{

    @CachePut(value = "nameCache", key = "#userId")
    public String setName(long userId, String name) {
        return name;
    }

    @Cacheable(value = "nameCache", key = "#userId")
    public String getName(long userId) {
        return "not cached";
    }

}

@Component
public class CacheReference {

    @Autowired
    private CacheObject cacheObject;

    public String getNameOut(long userId){
        return cacheObject.getName(userId);
    }
}

@Configuration
public class SystemConfig {

    @Autowired
    private CacheObject cacheObject;

    @PostConstruct
    public void init(){
        System.out.println("------------------");
        System.out.println("-- PRE LOAD CACHE BUT DIDN'T GET CACHED");
        System.out.println("------------------");

        cacheObject.setName(2, "neal");
        cacheObject.setName(3, "dora");

    }

}

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BootElastic.class)
@WebAppConfiguration
public class CacheTest {

    @Autowired
    private CacheObject cacheObject;
    @Autowired
    private CacheReference cacheReference;

    @Test
    public void testCache(){

        String name = "this is neal for cache test";
        long userId = 1;

        cacheObject.setName(userId, name);
//        cacheObject.setName(2, "neal"); // this will make test success
        String nameFromCache = cacheReference.getNameOut(userId);
        System.out.println("1" + nameFromCache);
        Assert.assertEquals(nameFromCache, name);

    }

    @Test
    public void testCacheFromConfig(){
        String nameFromCache = cacheReference.getNameOut(2);
        System.out.println("4" + nameFromCache);
        Assert.assertEquals(nameFromCache, "neal");
    }
}

1 个答案:

答案 0 :(得分:1)

@PostConstruct方法在调用所有postProcessBeforeInitialization()BeanPostProcessor方法之后立即调用,并且在调用postProcessAfterInitialization()之前调用。所以在bean有任何代理之前调用它,包括一个,将值放到缓存中。 与@PostConstruct中不能使用@Transactional或@Async方法的原因相同。

您可以从ContextRefreshedEvent上的某些@EventListener调用它来使其正常工作