Как кэшировать метод с двумя параметрами в Spring-Mvc - PullRequest
1 голос
/ 11 мая 2019

Я хочу преобразовать поля суммы транзакций в другую валюту, и я решил использовать механизм кэширования с аннотациями @Cacheable. В этом кешируемом методе я вызываю метод остальные API, чтобы получить курс валюты. В соответствии с тем, что я устанавливаю период кэширования равным 60 секундам и всегда отправляю одни и те же параметры, программа выполняет кешируемые методы для каждой предстоящей транзакции.

Я хочу видеть журналы за каждую минуту или вызывать другой параметр, из-за этого я использовал log.error ().

CurrencyConverterService.java

@Service
public class CurrencyConverterService {
    private Logger log = LogManager.getLogger(CurrencyConverterService.class);
    @Autowired
    private ICurrencyService currencyService;

    int counter=0;

    @Cacheable(value = "allCurrency")
    public Float getCurrencyRate(String targetCurrCode, String baseCurrCode){
        log.error("getCurrencyRate called " +targetCurrCode +" - "+baseCurrCode+" - counter "+ counter+" Times");
        counter++;
        Float rate = currencyService.calculateParity(targetCurrCode, baseCurrCode);
        return rate;
    }

    public BigDecimal currencyConverter(Object value, String targetCurrCode, String baseCurrCode){
        float rate;

        if (baseCurrCode.equals(targetCurrCode)){
            rate = 1.0f;
        }else{
            rate = getCurrencyRate(targetCurrCode, baseCurrCode);
        }
        return ((BigDecimal)value).multiply(new BigDecimal(rate));
    }
}

Demo.java

@Service
public class Demo{
    @Autowired
    public ApplicationContext appContext;
    public CurrencyConverterService currencyConverterService;

    public void getCurrencyFromAPI(Object value, String targetCurrCode, String baseCurrCode){
        ....
        currencyConverterService = (CurrencyConverterService) appContext.getBean("currencyConverterService");
        currencyConverterService.currencyConverter(value, targetCurrCode, baseCurrCode);
        ....

    }
}

ehcache.xml

<ehcache
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false" monitoring="off" dynamicConfig="true">

    <diskStore path="java.io.tmpdir"/>

    <cache
            name="allCurrency"
            eternal="false"
            maxElementsInMemory="200"
            maxElementsOnDisk="10000"
            timeToIdleSeconds="600"
            timeToLiveSeconds="600"
            overflowToDisk="true"
            diskExpiryThreadIntervalSeconds="86400"
            memoryStoreEvictionPolicy="LFU"/>
</ehcache>

Если я отправлю 1000 транзакций за четыре минуты. Я вижу результаты ниже;

getCurrencyRate вызываетdddd EUR-USD - счетчик 1 раз
getCurrencyRate calldddd EUR-USD - счетчик 2 раза
...
getCurrencyRate calldddd EUR-USD - счетчик 999 раз
getCurrencyRate calldddd EUR-USD - счетчик 1000 раз

но я хочу видеть как ниже;

getCurrencyRate звонилдд EUR-USD - счетчик 1 раз
getCurrencyRate calldddd EUR-USD - счетчик 2 раза
getCurrencyRate calldddd EUR-USD - счетчик 3 раза
getCurrencyRate calldddd EUR-USD - счетчик 4 раза

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 13 мая 2019

Я исправил эту проблему. Если я вызываю кэшированный метод из других методов в том же классе, как описано выше, не работает. Если я вызываю напрямую кэшированный метод из других классов, работает правильно. Я должен использовать, как показано ниже;

Demo.java

@Service
public class Demo{
    @Autowired
    public ApplicationContext appContext;
    public CurrencyConverterService currencyConverterService;

    public void getCurrencyFromAPI(Object value, String targetCurrCode, String baseCurrCode){
        ....
        currencyConverterService = (CurrencyConverterService) appContext.getBean("currencyConverterService");
        currencyConverter(value, targetCurrCode, baseCurrCode);
        ....

    }

    public BigDecimal currencyConverter(Object value, String targetCurrCode, String baseCurrCode){
        float rate;

        if (baseCurrCode.equals(targetCurrCode)){
            rate = 1.0f;
        }else{
            rate = currencyConverterService.getCurrencyRate(targetCurrCode, baseCurrCode);
        }
        return ((BigDecimal)value).multiply(new BigDecimal(rate));
    }

}

CurrencyConverterService.java

@Service
public class CurrencyConverterService {
    private Logger log = LogManager.getLogger(CurrencyConverterService.class);
    @Autowired
    private ICurrencyService currencyService;

    int counter=0;

    @Cacheable(value = "allCurrency")
    public Float getCurrencyRate(String targetCurrCode, String baseCurrCode){
        log.error("getCurrencyRate called " +targetCurrCode +" - "+baseCurrCode+" - counter "+ counter+" Times");
        counter++;
        Float rate = currencyService.calculateParity(targetCurrCode, baseCurrCode);
        return rate;
    }
}
...