簡體   English   中英

使用 @Cacheable 的 Spring 緩存在啟動時不起作用 @PostConstruct

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM