Java 如果Couchbase连接失败,如何在运行时禁用缓存?

Java 如果Couchbase连接失败,如何在运行时禁用缓存?,java,spring,spring-mvc,couchbase,spring-cache,Java,Spring,Spring Mvc,Couchbase,Spring Cache,我有一个与这里所问的类似的问题-。我的应用程序在服务层使用大多数数据库/静态资源调用 缓存由Couchbase支持,每当应用程序无法连接Couchbase节点时,应用程序就会关闭。这是我们不期望的,我们期望在连接失败时从源系统提供数据 我们尝试了实现,但没有达到预期效果,因为我们希望执行实际的方法,即发出服务调用并返回响应,而不是记录缓存失败,基本上绕过缓存,一旦Couchbase节点启动或建立连接,就从缓存中获取数据 知道我们如何实现它吗?谢谢@Daniel Bickler的建议,下面是我针对

我有一个与这里所问的类似的问题-。我的应用程序在服务层使用大多数数据库/静态资源调用

缓存由
Couchbase
支持,每当应用程序无法连接
Couchbase
节点时,应用程序就会关闭。这是我们不期望的,我们期望在连接失败时从源系统提供数据

我们尝试了实现,但没有达到预期效果,因为我们希望执行实际的方法,即发出服务调用并返回响应,而不是记录缓存失败,基本上绕过缓存,一旦Couchbase节点启动或建立连接,就从缓存中获取数据


知道我们如何实现它吗?

谢谢@Daniel Bickler的建议,下面是我针对@John Blum编写的实现

CouchbaseCustomCacheManager

import java.util.Map;
import org.springframework.cache.Cache;
import com.couchbase.client.spring.cache.CacheBuilder;
import com.couchbase.client.spring.cache.CouchbaseCacheManager;

public class CouchbaseCustomCacheManager extends CouchbaseCacheManager {

    public CouchbaseCustomCacheManager(
            final Map<String, CacheBuilder> initialCaches) {
        super(initialCaches);
    }

    @Override
    public Cache getCache(String name) {
        return new CouchbaseCacheWrapper(super.getCache(name));
    }

    protected static class CouchbaseCacheWrapper implements Cache {

        private final Cache delegate;

        public CouchbaseCacheWrapper(Cache couchbaseCache) {
            this.delegate = couchbaseCache;
        }

        @Override
        public String getName() {
            try {
                return delegate.getName();
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public Object getNativeCache() {
            try {
                return delegate.getNativeCache();
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public ValueWrapper get(Object key) {
            try {
                return delegate.get(key);
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public <T> T get(Object key, Class<T> type) {
            try {
                return delegate.get(key, type);
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public void put(Object key, Object value) {
            try {
                delegate.put(key, value);
            } catch (Exception e) {
                try {
                    handleErrors(e);
                } catch (Exception e1) {
                }
            }
        }

        @Override
        public ValueWrapper putIfAbsent(Object key, Object value) {
            try {
                return delegate.putIfAbsent(key, value);
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        public void evict(Object key) {
            try {
                delegate.evict(key);
            } catch (Exception e) {
                try {
                    handleErrors(e);
                } catch (Exception e1) {
                }
            }
        }

        @Override
        public void clear() {
            try {
                delegate.clear();
            } catch (Exception e) {
                try {
                    handleErrors(e);
                } catch (Exception e1) {
                }
            }
        }

        protected <T> T handleErrors(Exception e) throws Exception {
            if (e instanceof Exception) {
                return null;
            } else {
                throw e;
            }
        }
    }

}
import java.util.Map;
导入org.springframework.cache.cache;
导入com.couchbase.client.spring.cache.CacheBuilder;
导入com.couchbase.client.spring.cache.CouchbaseCacheManager;
公共类CouchbaseCustomCacheManager扩展了CouchbaseCacheManager{
公共CouchbaseCustomCacheManager(
最终地图初始值(缓存){
超级缓存;
}
@凌驾
公共缓存getCache(字符串名称){
返回新的CouchbaseCacheWrapper(super.getCache(name));
}
受保护的静态类CouchbaseCacheWrapper实现缓存{
私有最终缓存委托;
公共CouchbaseCacheWrapper(缓存couchbaseCache){
this.delegate=couchbaseCache;
}
@凌驾
公共字符串getName(){
试一试{
返回delegate.getName();
}捕获(例外e){
返回null;
}
}
@凌驾
公共对象getNativeCache(){
试一试{
返回delegate.getNativeCache();
}捕获(例外e){
返回null;
}
}
@凌驾
public ValueWrapper get(对象键){
试一试{
返回delegate.get(key);
}捕获(例外e){
返回null;
}
}
@凌驾
公共T获取(对象键,类类型){
试一试{
返回delegate.get(键,类型);
}捕获(例外e){
返回null;
}
}
@凌驾
公共void put(对象键、对象值){
试一试{
delegate.put(键、值);
}捕获(例外e){
试一试{
手误(e);
}捕获(异常e1){
}
}
}
@凌驾
public ValueWrapper putIfAbsent(对象键、对象值){
试一试{
返回委托putIfAbsent(键、值);
}捕获(例外e){
返回null;
}
}
@凌驾
公共无效收回(对象键){
试一试{
委托。逐出(键);
}捕获(例外e){
试一试{
手误(e);
}捕获(异常e1){
}
}
}
@凌驾
公共空间清除(){
试一试{
delegate.clear();
}捕获(例外e){
试一试{
手误(e);
}捕获(异常e1){
}
}
}
受保护的T handleErrors(异常e)引发异常{
如果(异常的实例){
返回null;
}否则{
投掷e;
}
}
}
}
并将其用作:

@Bean
public CacheManager cacheManager() {
    final Map<String, CacheBuilder> cache = new HashMap<>();
    for (final String appCache : "127.0.0.1,127.0.0.2,127.0.0.3".split(",")) {
     cache.put(appCache, CacheBuilder.newInstance(CouchbaseCluster.create().openBucket(
                    "default", "")));
    }
    return new CouchbaseCustomCacheManager(cache);
}
@Bean
公共缓存管理器缓存管理器(){
最终映射缓存=新HashMap();
对于(最终字符串appCache:“127.0.0.1127.0.0.2127.0.0.3”。拆分(“,”){
cache.put(appCache,CacheBuilder.newInstance(CouchbaseCluster.create().openBucket(
“默认值”、“默认值”);
}
返回新的CouchbaseCustomCacheManager(缓存);
}

这个问题的答案有什么不对?它似乎可以使用Spring缓存框架处理您需要的情况。@您提到的DanielBickler回答说明了如何处理缓存连接故障,但我所寻找的基本上是绕过缓存,在连接不可用时执行方法定义,并在连接建立后立即从缓存中获取数据。尝试访问缓存并处理异常的位置。如果是连接异常,则返回null。对不起,忽略我的最后一条评论。我在手机上看了看,结果我找到了错误的答案。如何确定连接的状态?如果可以确定连接的状态,则可以执行与第一个答案类似的操作,即在没有连接时包装缓存的一部分并模拟缓存未命中。@DanielBickler感谢您的建议“在没有连接时模拟缓存未命中”是关键。