我使用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");
}
}
答案 0 :(得分:0)
尝试使用ApplicationStartedEvent
代替@PostConstruct
注释。
我遇到了同样的问题,这个小小的改动解决了它。
您应该添加
@EventListener(classes = ApplicationStartedEvent.class)
在您的方法和传递之上
ApplicationStartedEvent event
作为参数。
示例:
@EventListener(classes = ApplicationStartedEvent.class)
void init(ApplicationStartedEvent event) {
MyObject o = service.myMethod("someString");
}
答案 1 :(得分:-1)
@PostConstruct将适用于您的情况。在实例化方法bean之后,将调用带有@PostConstruct注释的方法。
但是如果依赖于其他bean,那么在应用程序上下文完全启动后你会调用你的方法吗?你可以像这样创建一个新的bean:
websocket.onmessage = function (event) {
document.getElementById("foto").src = "data:image/png;event.data)";
};
答案 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();
}
}