From 331b628511b53dc4612c0cee250bf8cb49fe496b Mon Sep 17 00:00:00 2001 From: oldrat Date: Tue, 10 Jul 2012 15:27:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=80=E5=8D=95Cache=20Uti?= =?UTF-8?q?l=E5=AE=9E=E7=8E=B0=20DUBBO-475=20ReferenceConfig=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8C=89group+interface+version=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/utils/ReferenceConfigCache.java | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/utils/ReferenceConfigCache.java diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/utils/ReferenceConfigCache.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/utils/ReferenceConfigCache.java new file mode 100644 index 000000000..456cd1d9b --- /dev/null +++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/utils/ReferenceConfigCache.java @@ -0,0 +1,149 @@ +/* + * Copyright 1999-2011 Alibaba Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubbo.config.utils; + +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubbo.config.ReferenceConfig; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * a simple util class for cache {@link ReferenceConfig}. + *

+ * {@link ReferenceConfig} is a heavy Object, it's necessary to cache these object + * for the framework which create {@link ReferenceConfig} frequently. + *

+ * You can implement and use your own {@link ReferenceConfig} cache if you need use complicate strategy. + * + * @author ding.lid + */ +public class ReferenceConfigCache { + public static final String DEFAULT_NAME = "_DEFAULT_"; + + private static final ConcurrentMap cacheHolder = new ConcurrentHashMap(); + + /** + * Get the cache use default name and {@link #DEFAULT_KEY_GENERATOR} to generate cache key. + * Create cache if not existed yet. + */ + public static ReferenceConfigCache getCache() { + return getCache(DEFAULT_NAME); + } + + /** + * Get the cache use specified name and {@link KeyGenerator}. + * Create cache if not existed yet. + */ + public static ReferenceConfigCache getCache(String name) { + return getCache(name, DEFAULT_KEY_GENERATOR); + } + + /** + * Get the cache use specified {@link KeyGenerator}. + * Create cache if not existed yet. + */ + public static ReferenceConfigCache getCache(String name, KeyGenerator keyGenerator) { + ReferenceConfigCache cache = cacheHolder.get(name); + if(cache != null) { + return cache; + } + cacheHolder.putIfAbsent(name, new ReferenceConfigCache(name, keyGenerator)); + return cacheHolder.get(name); + } + + public static interface KeyGenerator { + String generateKey(ReferenceConfig referenceConfig); + } + + /** + * Create the key with the Group, Interface and version attribute of {@link ReferenceConfig}. + *

+ * eg: group1/com.alibaba.foo.FooService:1.0.0. + */ + public static final KeyGenerator DEFAULT_KEY_GENERATOR = new KeyGenerator() { + public String generateKey(ReferenceConfig referenceConfig) { + String iName = referenceConfig.getInterface(); + if(StringUtils.isBlank(iName)) { + Class clazz = referenceConfig.getInterfaceClass(); + iName = clazz.getName(); + } + if(StringUtils.isBlank(iName)) { + throw new IllegalArgumentException("No interface info in ReferenceConfig" + referenceConfig); + } + + StringBuilder ret = new StringBuilder(); + if(! StringUtils.isBlank(referenceConfig.getGroup())) { + ret.append(referenceConfig.getGroup()).append("/"); + } + ret.append(iName); + if(! StringUtils.isBlank(referenceConfig.getVersion())) { + ret.append(":").append(referenceConfig.getVersion()); + } + return ret.toString(); + } + }; + + private final String name; + private final KeyGenerator generator; + + private ConcurrentMap> cache = new ConcurrentHashMap>(); + + private ReferenceConfigCache(String name, KeyGenerator generator) { + this.name = name; + this.generator = generator; + } + + public T get(ReferenceConfig referenceConfig) { + String key = generator.generateKey(referenceConfig); + + ReferenceConfig config = cache.get(key); + if(config != null) { + return referenceConfig.get(); + } + + cache.putIfAbsent(key, referenceConfig); + config = cache.get(key); + return (T) config.get(); + } + + void destroyKey(String key) { + ReferenceConfig config = cache.remove(key); + if(config == null) return; + config.destroy(); + } + + /** + * clear and destroy one {@link ReferenceConfig} in the cache. + * @param referenceConfig use for create key. + */ + public void destroy(ReferenceConfig referenceConfig) { + String key = generator.generateKey(referenceConfig); + destroyKey(key); + } + + /** + * clear and destroy all {@link ReferenceConfig} in the cache. + */ + public void destroyAll() { + Set set = new HashSet(cache.keySet()); + for(String key : set) { + destroyKey(key); + } + } +} -- GitLab