[英]Spring cache using @Cacheable during @PostConstruct does not work
[英]Spring cache using @Cacheable not working on startup @PostConstruct
我正在使用 Spring,我想在啟動我的應用程序之前緩存一些數據。
我在其他帖子中找到了一些使用@PostConstruct 來調用我的@Service 方法(注釋為@Cacheable)的解決方案,例如。 如何在春季啟動時加載@Cache? 我這樣做了,但是當應用程序啟動后,我調用 REST 端點,它再次調用此服務方法,它再次發送數據庫請求(因此它尚未緩存)。 當我第二次向端點發送請求時,數據被緩存。
結論是在@PostConstruct 上調用 Service 方法不會導致從數據庫緩存數據。
是否可以在啟動應用程序之前緩存數據? 我怎樣才能做到這一點? 下面是我的代碼片段。
@RestController
class MyController {
private static final Logger logger = LoggerFactory.getLogger(MyController.class);
@Autowired
MyService service;
@PostConstruct
void init() {
logger.debug("MyController @PostConstruct started");
MyObject o = service.myMethod("someString");
logger.debug("@PostConstruct: " + o);
}
@GetMapping(value = "api/{param}")
MyObject myEndpoint(@PathVariable String param) {
return service.myMethod(param);
}
}
@Service
@CacheConfig(cacheNames = "myCache")
class MyServiceImpl implements MyService {
@Autowired
MyDAO dao;
@Cacheable(key = "{ #param }")
@Override
public MyObject myMethod(String param) {
return dao.findByParam(param);
}
}
interface MyService {
MyObject myMethod(String param);
}
@Repository
interface MyDAO extends JpaRepository<MyObject, Long> {
MyObject findByParam(String param);
}
@SpringBootApplication
@EnableConfigurationProperties
@EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Primary
@Bean
public CacheManager jdkCacheManager() {
return new ConcurrentMapCacheManager("myCache");
}
}
嘗試使用ApplicationStartedEvent
而不是@PostConstruct
注釋。
我遇到了同樣的問題,這個小改動修復了它。
您應該在方法@EventListener(classes = ApplicationStartedEvent.class)
添加@EventListener(classes = ApplicationStartedEvent.class)
並將ApplicationStartedEvent event
作為參數傳遞。
例子:
@EventListener(classes = ApplicationStartedEvent.class)
void init(ApplicationStartedEvent event) {
MyObject o = service.myMethod("someString");
}
@PostConstruct 將適用於您的情況。 帶有@PostConstruct 注釋的方法將在方法 bean 實例化后立即調用。
但是,如果您依賴其他 bean 並且在應用程序上下文完全啟動后調用您的方法? 你可以像這樣創建一個新的bean:
@Component
public class MyListener
implements ApplicationListener<ContextRefreshedEvent> {
public void onApplicationEvent(ContextRefreshedEvent event) {
//Here call your method of cache
// Your methode will be called after the application context has fully started
}
}
在Spring 1.3及更高版本中:
@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private MyService service;
/**
* This event is executed as late as conceivably possible to indicate that
* the application is ready to service requests.
*/
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
service.myMethod();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.