Assume you have methods that (almost) always return the same result for the same input arguments. If preparing method result is a heavy operation and/or it consumes time, it is reasonable to cache these results.
One way of building method cache in Tapestry5 is by implementing MethodAdvice interface like this:
public class CacheMethodResultAdvice implements MethodAdvice {
private static final Logger logger = LoggerFactory.getLogger(CacheMethodResultAdvice.class);
private final Cache cache;
private final Class<?> advisedClass;
private final Object nullObject = new Object();
public CacheMethodResultAdvice(Class<?> advisedClass, Cache cache) {
this.advisedClass = advisedClass;
this.cache = cache;
}
@Override
public void advise(Invocation invocation) {
String invocationSignature = getInvocationSignature(invocation);
String entityCacheKey = String.valueOf(invocationSignature.hashCode());
Object result;
if (cache.containsKey(entityCacheKey))
{
result = cache.get(entityCacheKey);
logger.debug("Using invocation result ({}) from cache '{}'", invocationSignature, result);
invocation.overrideResult(result);
}
else
{
invocation.proceed();
if (!invocation.isFail())
{
result = invocation.getResult();
cache.put(entityCacheKey, result);
}
}
}
private String getInvocationSignature(Invocation invocation) {
StringBuilder builder = new StringBuilder(150);
builder.append(advisedClass.getName());
builder.append('.');
builder.append(invocation.getMethodName());
builder.append('(');
for (int i = 0; i < invocation.getParameterCount(); i++) {
if (i > 0) {
builder.append(',');
}
Class<?> type = invocation.getParameterType(i);
builder.append(type.getName());
builder.append(' ');
Object param = invocation.getParameter(i);
builder.append(param != null ? param : nullObject);
}
builder.append(')');
return builder.toString();
}
} Implementation of
getInvocationSignature(...) is not ideal, but you may improve it to match your requirements. One issue I see here is building invocation signature for
null-value parameters in a clustered environment (which is GAE). In this implementation method
nullObject.toString() will return something like
java.lang.Object@33aa9b. And this value will vary in different instances of your application. You may replace
nullObject with just
"null" string. Just keep in mind that
"null" != null.
Tapestry5方法结果缓存
本文介绍如何在Tapestry5中实现方法结果的缓存,通过自定义MethodAdvice来减少重复计算,提高应用性能。具体展示了如何根据不同业务需求配置不同的缓存策略。
4223

被折叠的 条评论
为什么被折叠?



