Java静态冗余_项目冗余代码怎么处理?

从之前的大家的回答和讨论来看,微服务是被题主否定了,这肯定是多方面的考虑嘛,并且微服务只是一种方案的选择而已,也并不是一招吃遍天下的,很显然之前代码的处理肯定是按照引用一个通用工具jar包调用的方式处理,所以改为微服务的话,就算不谈此次缓存和数据库的修改逻辑来说,光架构方面的改动,调用方和提供方改动都还是比较大的。还有双方开发人员对于微服务的熟悉程度。

所以我起初看到这个问题的时候,我反而还没有想用微服务的,因为从题主的描述来看,我感觉他更希望用一种结合Spring整合缓存,然后替换之前的工具包里的逻辑而已,这样相当于只是改了之前工具包里的逻辑,就算调用接口被改,调用方修改的代价也是比较小的,改改方法名和入参而已。

因此我谈谈我自己的看法吧,我能想到的Spring整合缓存那肯定是Spring Cache,Spring作为一个整合框架,要的就是一招可以针对某个业务提出统一接口,然后第三方实现,相当于Spring项目级别的SPI,那对于Cache来说,Spring也有抽象有一套接口和注解,可以搜索直接Spring Cache,简单了解一下用法即可

回到题主的需求上,需要读数据库+redis+本地缓存,那其实我自己理解这应该就是本地缓存作为一级缓存,redis作为二级缓存,最后再去读DB

那这跟Spring Cache的方法注解@Cacheable就有类似的效果了

@Cacheable标注一个方法,提供缓存的name,对应的key,以及使用哪个CacheManager处理,例如下面的例子一样@Cacheable(cacheNames = "DIRTY_DATA", key = "'all_dirty_data'", cacheManager = "CACHE_MANAGER")

public List all() {

return Arrays.asList("data1", "data2");

}

如果这次操作的CacheManager返回为null,那就执行方法all(),并且方法all()的值最后会被交给CacheManager中的Cache做处理缓存起来

如上的描述其实基本就满足了题主的需求,只是有一点,题主是有两级缓存的,刚刚的描述好像没有提到,其实不然,我们来看Spring的CacheManager的接口定义

b7529eee99ae70ff72c6f5382f2956cc.png

根据缓存的name返回一个Cache,其实Cache就是某种类型的缓存的抽象,比如有Redis的实现RedisCache,EhCache的实现EhCacheCache等等。

但是CacheManager的定义是根据name返回一个Cache,也没有指定要什么类型的(虽然RedisCache和EhCacheCache都有他们自己的CacheManager),所以CacheManager管理的Cache理论是可以有多不同类型的实现。当然不用题主定义,Spring想好了,请看CompositeCacheManager

25fedb6e7c5c9be711f8a5d704aa1cb0.png

CompositeCacheManager如其名,组合的CacheManager,虽然有不同类型的Cache实现,也有不同的CacheManager类型实现,现在CompositeCacheManager就可以把不同类型的CacheManager合在一起,因为合在一起的方式是集合List,而集合是有顺序的,所以题主这下应该明白为啥可以实现两级缓存了叭,这就是我的想法

那废话不多说,只要题主了解一下Spring Cache的相关知识,接下来我的做法应该可以理解了

本地缓存我就以EhCache举例吧,我主要展示Cache的配法,其他的配置就不展示了哈

那我们先配置一个EhCache的CacheManager: EhCacheCacheManager@Autowired

private CacheProperties cacheProperties;

@Bean

public EhCacheCacheManager ehCacheCacheManager() {

Resource location = this.cacheProperties.resolveConfigLocation(this.cacheProperties.getEhcache().getConfig());

return new EhCacheCacheManager(EhCacheManagerUtils.buildCacheManager(location));

}

接下来再配一个Redis的CacheManager:RedisCacheManager@Bean

public RedisCacheManager redisCacheManager(RedisConnectionFactory factory) {

RedisCacheManager cacheManager = RedisCacheManager.builder(factory)

.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig())

.build();

return cacheManager;

}

两个CacheManager都有了,关键的,我们再配置一个新的CacheManager:CompositeCacheManager@Bean

@Primary

public CompositeCacheManager compositeCacheManager(EhCacheCacheManager ehCacheCacheManager, RedisCacheManager redisCacheManager) {

return new CompositeCacheManager(ehCacheCacheManager, redisCacheManager);

}

注意上面的顺序哈,如果想要优先EhCache命中,当然EhCacheCacheManager就要放在构造方法的参数中的最前面哈,并且为了@Cacheable配置起来很简洁,我们加一个@Primary,因为现在有三个CacheManager了,这样的话,我们使用@Cacheable就可以不用指定那个cacheManager参数了

其次,为了CompositeCacheManager和@Cacheable能关联起来,我们需要配置一个CacheResolver@Bean

public CacheResolver cacheResolver(CompositeCacheManager compositeCacheManager) {

return new SimpleCacheResolver(compositeCacheManager);

}

最后,就是如何使用了,假设对外提供了一个脏数据查询的接口public interface IDirtyDataService {

List all();

}

那它的实现可以这样写@Service

public class DirtyDataServiceImpl implements IDirtyDataService {

@Override

@Cacheable(cacheNames = {"EHCACHE_DIRTY_DATA", "REDIS_DIRTY_DATA"}, key = "'all_dirty_data'")

public List all() {

return Arrays.asList("data1", "data2");

}

}

非常简单哈,这其中的cacheNames中的EHCACHE_DIRTY_DATA,是和你配置的EhCache的名字一样哈,因为EhCache的配置是xml的,所以xml里的名字要和这里一致

c84f53e78dbed47f3b6fb0253bb6be3e.png

至于Redis的REDIS_DIRTY_DATA,这个可以随意了,毕竟没有的话,默认情况下,它是可以自己造一个的,参考RedisCacheManager的getMissingCache

4d4606dc2d9bcf888e279dcafe2ee90c.png

我把完整代码放到github上吧,我提供的方案只是我自己对于你描述的业务的理解,虽然不一定能解决你的问题,不过Spring Cache是你可以考虑的方向哈

那就这样叭~拜了个拜(ˉ▽ ̄~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值