Я пытаюсь написать простой механизм кэширования на Java.Он должен кэшировать вызовы веб-службы и результаты.Использование должно быть максимально простым.Поэтому я хотел бы использовать лямбда-выражения, подобные следующему примеру:
// normal call without caching
Result result1 = service.callMethodA("Parameter1");
// call with cache
Result result2 = Cache.executeWithCache(() -> service.callMethodA("Parameter1"));
Моя проблема здесь в том, что Мне нужно вычислить ключ кэша для вызова на основе заданного
- тип сервиса (получить имя типа из экземпляра объекта)
- метод сервиса (получить имя вызываемого метода)
- параметры (массив с типом и значением)
Но я не смог получить эту информацию в Java из тела лямбда-выражения.Я пытался использовать Supplier<T>
в executeWithCache
методе, но кажется, что это невозможно.
Единственный способ предоставить эту информацию, который я нашел, - это установить непосредственно в вызове.Но это не очень удобно.Как:
Result result = Cache.executeWithCache(service, "callMethodA", new Object[] {"Parameter1"});
У кого-нибудь есть идея получить эту информацию из лямбда-звонка?
Спасибо Томасу
ПРИМЕЧАНИЕ:
Я реализовал это с помощью C # в одном из моих других приложений.Там я использую дженерики и MethodCallExpression
, который прекрасно работает:
public ServiceDataCacheResult<T> ExecuteWithCache<T>(Expression<Func<T>> serviceMethodExpression)
{
ThrowIfDisposed();
var methodExpression = serviceMethodExpression.Body as MethodCallExpression;
if (methodExpression == null)
{
throw new NotSupportedException(
"Only Expressions with body of type MethodCallExpression are supported!");
}
var cacheKey = GenerateCacheKey(methodExpression.Method, methodExpression.Arguments);
if (_cacheStore.Contains(cacheKey))
{
var existingCacheValue = (ServiceDataCacheItem<T>) _cacheStore.Get(cacheKey);
// Check for equality too because hashing can have collisions
if (EqualExpressions(existingCacheValue.Expression, methodExpression))
{
return new ServiceDataCacheResult<T>
{
Value = existingCacheValue.Value,
CacheKey = cacheKey,
CreatedTime = existingCacheValue.CreatedTime,
ExpirationTime = existingCacheValue.ExpirationTime,
GotFromCache = true,
StoredToCache = false
};
}
}
// compile and execute method
var result = serviceMethodExpression.Compile()();
var createdTime = DateTime.Now;
var expireTime = createdTime.Add(ItemLifeTime);
var newCacheValue = new ServiceDataCacheItem<T>
{
Value = result,
Expression = methodExpression,
CreatedTime = createdTime,
ExpirationTime = expireTime
};
_cacheStore.Add(cacheKey, newCacheValue, new CacheItemPolicy
{
AbsoluteExpiration = expireTime
});
return new ServiceDataCacheResult<T>
{
Value = result,
CacheKey = cacheKey,
CreatedTime = newCacheValue.CreatedTime,
ExpirationTime = newCacheValue.ExpirationTime,
GotFromCache = false,
StoredToCache = true
};
}
Позвоните через:
ServiceDataCacheResult<Result> result = Cache.ExecuteWithCache(() => service.CallMethodA("Parameter1"));