gpt4 book ai didi

java - Spring @Cacheable、@CachePut 不适用于另一个代理类

转载 作者:行者123 更新时间:2023-12-01 19:59:19 27 4
gpt4 key购买 nike

这是我的 ProductServiceImpl 类。

public class ProductServiceImpl implements ProductService {

@Autowired
GalaxyService gs ;

@PostConstruct
private void init() {
int hash = Objects.hash("Galaxy");
gs.updateByName(hash);

}

@Override
@Cacheable(value = "products", key = "T(java.util.Objects).hash(#p0)")
public String getByName(String name) {
System.out.println("Inside method");
slowLookupOperation();
return name + " : " + name;
}

@CacheEvict(value = "products", allEntries = true)
public void refreshAllProducts() {
//This method will remove all 'products' from cache, say as a result of flush API.
}

public void slowLookupOperation() {
try {
long time = 5000L;
Thread.sleep(time);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}}

这是我的 GalaxyServiceImpl:

public class GalaxyServiceImpl implements GalaxyService {

@Override
@CachePut(value = "products", key = "#key")
public String updateByName(Integer key) {
return "Oh My Galaxy- " + key;
}}

通过 ProductServiceImpl 的 init() 方法,我正在更新缓存元素。看起来 Spring 缓存没有缓存该方法。

但是,我是从我的主类中执行此操作的,它正在缓存该方法。主要类如下:

    public mainconstructor() {

AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
ProductService service = (ProductService) context.getBean("productService");

GalaxyService gs = (GalaxyService) context.getBean("galaxy");


int hash = Objects.hash("Galaxy");
gs.updateByName(hash);

System.out.println("Galaxy S8 ->" + service.getByName("Galaxy"));

((AbstractApplicationContext) context).close();
}

我的应用程序配置类如下:

@EnableCaching
@Configuration
@ComponentScan(basePackages = {"com.websystique.spring", "com.samsung.gs8"})
public class AppConfig {

@Bean
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}

@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean factory = new EhCacheManagerFactoryBean();
factory.setConfigLocation(new ClassPathResource("ehcache.xml"));
factory.setShared(true);
factory.setAcceptExisting(false);
return factory;
}

@Bean
public GalaxyService galaxy() {
GalaxyService gs = new GalaxyServiceImpl();
return gs;
}}

完整代码可在- https://github.com/pijushcse/SpringCache获取

我的问题是,如果我想更新缓存项,ProductServiceImpl 出了什么问题?为什么它在 Main 类中有效,为什么在其他类中不起作用? TIA

最佳答案

简单的回答是:这是正常的。您不应在 @PostConstruct 中初始化缓存。

现在是长答案。 CacheInterceptor 很特殊。它是通过 initialized = false 创建的。然后,在一个特殊的回调SmartInitializingSingleton中,它进入initialized = true。所有 bean 初始化后都会调用此回调。在此之前,它不会缓存任何内容。

底线,您无法在 @PostConstruct 中预先缓存某些内容。

最好的解决方案是自己触发缓存。无论如何,它可能更干净,并且提供了更多的灵 active 。所以 getBean 是有道理的。

关于java - Spring @Cacheable、@CachePut 不适用于另一个代理类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48528284/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com