Сделать Spring Cache доступным при запуске сервера или вызове планировщика - PullRequest
0 голосов
/ 08 марта 2019

У меня есть таблица материалов с основными данными (около 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;
    }
}

Результаты

После запуска сервера

  1. Будет напечатано «ВЫЗОВ ПРИ ЗАПУСКЕ».
  2. "Получение из БД" печатается.
  3. Звонок / материалы от чванства
  4. Снова "Получение из БД" печатается.
  5. Звонок / материалы от чванства Опять
  6. Ответ получается быстро, а «Получение из БД» не печатается

Такое же поведение наблюдается при вызове getMaterials () из планировщика. Какие-нибудь мысли?

...