【发布时间】:2017-06-01 15:41:14
【问题描述】:
我正在使用 Spring,我想在启动我的应用程序之前缓存一些数据。
我在其他帖子中找到了一些使用@PostConstruct 调用我的@Service 方法(注解为@Cacheable)的解决方案,例如。 How to load @Cache on startup in spring? 我这样做了,但是当应用程序启动后我调用 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");
}
}
【问题讨论】:
-
尝试在
@PostConstruct中执行此操作通常是一个坏主意,它可能会过早运行(没有创建代理,因此没有应用 AOP)。最好在侦听ContextRefreshedEvents 的ApplicationListener中执行此类操作。那就是告诉你一切都已经开始的触发器,你现在可以调用缓存方法了。 -
@M.Deinum 好的,但我需要在启动 REST 端点并侦听请求之前启动缓存。我该怎么做?
-
一旦 dispatcherservlet 启动,它就会在监听...如前所述,使用
ApplicationListener以确保安全。 -
@M.Deinum 谢谢,这解决了我的问题!
标签: java spring caching spring-cache