首页 文章

使用@Cacheable的Spring缓存不能在启动时使用@PostConstruct

提问于
浏览
1

我正在使用Spring,我想在启动应用程序之前缓存一些数据 .

我在其他帖子中找到了一些解决方案来使用@PostConstruct来调用我的@Service方法(注释为@Cacheable),例如 . How to load @Cache on startup in spring?我这样做但是在应用程序启动后我调用REST endpoints 再次调用此服务方法它's sending database request another time (so it'尚未缓存) . 当我第二次向 endpoints 发送请求时,数据被缓存 .

结论是在@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");
    }
}

2 回答

  • -1

    使用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();
    
      }
    
    }
    
  • -1

    @PostConstruct将适用于您的情况 . 在实例化方法bean之后,将调用带有@PostConstruct注释的方法 .

    但是,如果您依赖其他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
        }
    }
    

相关问题