dubbo-filter 源码分析

本文探讨Dubbo框架中的缓存机制,包括LruCache、ThreadLocalCache及JCache的实现方式,同时深入解析CacheFilter如何应用这些缓存策略。此外,还介绍了Dubbo的验证机制,包括Validator和ValidationFilter的使用,确保方法调用前参数的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明:这个模块的功能是缓存调用结果,但是我有一个疑问,比如说开始调用的时候,返回结果列表中只有一条数据,另一个进程插入了一条数据,那么下一次调用缓存的那个方法时,那是返回一条结果,还是两条结果了?

Cache 接口定义了两个方法,put 和 get.

public interface Cache {
/**
* API to store value against a key
* @param key Unique identifier for the object being store.
* @param value Value getting store
*/
void put(Object key, Object value);

/**
 * API to return stored value using a key.
 * @param key Unique identifier for cache lookup
 * @return Return stored object against key
 */
Object get(Object key);

}

CacheFactory 定义了获取 Cache 的方法

@SPI(“lru”)
public interface CacheFactory {

/**
 * CacheFactory implementation class needs to implement this return underlying cache instance for method against
 * url and invocation.
 * @param url
 * @param invocation
 * @return Instance of Cache containing cached value against method url and invocation.
 */
@Adaptive("cache")
Cache getCache(URL url, Invocation invocation);

}

AbstractCacheFactory 实现了 CacheFactory 的基本骨架.

我们先看下 LruCache 吧,LruCache 是最近最久未使用,它的实现原理是借用了 LinkedHashMap 实现的.

public LruCache(URL url) {
final int max = url.getParameter(“cache.size”, 1000);
this.store = new LRUCache<>(max);
}

public class LruCacheFactory extends AbstractCacheFactory {

/**
 * Takes url as an method argument and return new instance of cache store implemented by LruCache.
 * @param url url of the method
 * @return ThreadLocalCache instance of cache
 */
@Override
protected Cache createCache(URL url) {
    return new LruCache(url);
}

}

ThreadLocalCache 是借助于 ThreadLocal 实现的.

JCache 是用于缓存的 Java API. 它提供一组通用的类和接口,可用于将 Java 对象临时存储在内存中. 所以即可以使用 JCache 实现,同样的,我也可以使用 Ecache 实现.

ExpiringMap 采用的 ConcurrentHashMap + Thread 实现可自动移除失效数据的结构,所以此处我认为采用 redis 实现效果会更好.

现在来重点关注下 CacheFilter 这个类. 这里实现了缓存结果的具体逻辑.

public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (cacheFactory != null && ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), CACHE_KEY))) {
Cache cache = cacheFactory.getCache(invoker.getUrl(), invocation);
if (cache != null) {
String key = StringUtils.toArgumentString(invocation.getArguments());
Object value = cache.get(key);
if (value != null) {
if (value instanceof ValueWrapper) {
return AsyncRpcResult.newDefaultAsyncResult(((ValueWrapper) value).get(), invocation);
} else {
return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
}
}
Result result = invoker.invoke(invocation);
if (!result.hasException()) {
cache.put(key, new ValueWrapper(result.getValue()));
}
return result;
}
}
return invoker.invoke(invocation);
}

dubbo-filter-validation 包

Validator 类的实例在实际方法调用前对方法输入参数执行验证的扩展.
public interface Validator {

void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception;

}

Validation 获取 Validator 的工厂接口
@SPI(“jvalidation”)
public interface Validation {

/**
 * Return the instance of {@link Validator} for a given url.
 * @param url Invocation url
 * @return Instance of {@link Validator}
 */
@Adaptive(VALIDATION_KEY)
Validator getValidator(URL url);

}

AbstractValidation 抽象类,实现 Validation 的基本骨架.

ValidationFilter 在实际调用方法前,通过 Validation 校验参数的合法性(这个类似于以前在前端使用的 validateEngine 一样,通用的数据校验API).

public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (validation != null && !invocation.getMethodName().startsWith("$")
&& ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
try {
Validator validator = validation.getValidator(invoker.getUrl());
if (validator != null) {
validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
}
} catch (RpcException e) {
throw e;
} catch (Throwable t) {
return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
}
}
return invoker.invoke(invocation);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值