У меня есть таблица материалов с основными данными (около 10 тыс. Записей). Эти основные данные обновляются ежедневно с использованием канала из прежней системы (ночь 2.30 по тихоокеанскому времени). Когда интерфейсный системный вызов API, мы должны загрузить все материалы в устройство (IOS).
Я хочу использовать кеширование при загрузке пружины, чтобы во внешних системах не возникало задержек. Я создал весеннее загрузочное приложение, и кеширование работает нормально, когда я вызываю API из swagger. Первый раз занимает около 8-9 секунд, но после этого ответ быстрый.
Чтобы избежать первой задержки, я хочу загрузить весь материал в кеш -
1. При запуске сервера
2. Запустив планировщик после получения канала (сначала удалите все записи, затем загрузите новый)
Для # 1 я знаю, что postConstruct () не поможет, потому что прокси не будут доступны ко времени вызова postConstruct (). Я попытался использовать contextrefreshedevent и apllicationreadyevent, но на удивление это не сработало. Первый вызов API от чванства, идущего в БД для получения материалов. Второй звонок вперед работает нормально.
Для # 2 также, когда планировщик запускает, он вызывает метод для загрузки материалов. Но опять-таки Первый вызов API от чванства, идущего в БД для получения материалов. Второй звонок вперед работает нормально.
CachingConfig class
@Configuration
@EnableCaching
public class CachingConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("materials");
}
}
Интерфейс MaterialService
public interface MaterialService {
Iterable<Material> getMaterials();
}
MaterialServiceImpl class
@Service
public class MaterialServiceImpl implements MaterialService {
@Autowired
private MaterialRepository repository;
@Override
@Cacheable( "materials")
public Iterable<Material> getMaterials() {
Iterable<Material> all = repository.findAll();
logger.info("Getting from DB");
return all;
}
}
Класс CacheInitializer
@Component
public class CacheInitializer implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private MaterialService service;
@Override
public void onApplicationEvent( ApplicationReadyEvent event) {
logger.info("CALLING ON STARTUP");
service.getMaterials();
}
}
Класс MaterialController
@RestController
@RefreshScope
public class MaterialController {
@Autowired
private MaterialService service;
@GetMapping( value = "/materials", produces = MediaType.APPLICATION_JSON_VALUE)
public ServiceResponse<Iterable<Material>> getMaterials( @RequestHeader HttpHeaders headers) {
ServiceResponse<Iterable<Material>> response = new ServiceResponse<>();
response.setResult(service.getMaterials());
response.setStatusCode(HttpStatus.OK.toString());
response.setStatus(Status.SUCCESS);
return response;
}
}
Результаты
После запуска сервера
- Будет напечатано «ВЫЗОВ ПРИ ЗАПУСКЕ».
- "Получение из БД" печатается.
- Звонок / материалы от чванства
- Снова "Получение из БД" печатается.
- Звонок / материалы от чванства Опять
- Ответ получается быстро, а «Получение из БД» не печатается
Такое же поведение наблюдается при вызове getMaterials () из планировщика.
Какие-нибудь мысли?