公司需要改造现有的敏感词过滤机制, 从文件读取+本地缓存的方式变成, 读数据库+redis+本地缓存的方式;
这个任务交给了我, 之前的方式可以将敏感词库初始化, 过滤方法等代放在通用工具包中, 但是现在需要使用redis或者读取数据库等, 需要在spring的容器中被管理, 而敏感词过滤又被多个项目使用, 如过每个项目都写一遍的话, 改动的时候就很麻烦, 求指点更好的解决方案, 谢谢
公司需要改造现有的敏感词过滤机制, 从文件读取+本地缓存的方式变成, 读数据库+redis+本地缓存的方式;
这个任务交给了我, 之前的方式可以将敏感词库初始化, 过滤方法等代放在通用工具包中, 但是现在需要使用redis或者读取数据库等, 需要在spring的容器中被管理, 而敏感词过滤又被多个项目使用, 如过每个项目都写一遍的话, 改动的时候就很麻烦, 求指点更好的解决方案, 谢谢
旧系统十有八九是静态方法,调用直接了事,
改造的话,直接改调用的方法就行了;
需要注意的地方就是通常类也要使用bean:
因为涉及到db查询和redis,需要使用到相关的bean,在最小的改动下,可以通过实现ApplicationContextAware接口来获取applciationContext,有这玩意,就能在没有被容器管理的类也可以使用bean了
不过这种缺点的话 也很明显
如果是多个业务系统都要做这个功能,数据存在业务系统数据库的话,这部分表都要有
(我们这边就有这种业务,之前数据都是在一个单独的服务,后面为了精简那个服务的功能,将这一部分数据抽到业务系统了,现在业务系统都有一部分完全一样的表,感觉有点没必要)
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
从之前的大家的回答和讨论来看,微服务是被题主否定了,这肯定是多方面的考虑嘛,并且微服务只是一种方案的选择而已,也并不是一招吃遍天下的,很显然之前代码的处理肯定是按照引用一个通用工具
jar
包调用的方式处理,所以改为微服务的话,就算不谈此次缓存和数据库的修改逻辑来说,光架构方面的改动,调用方和提供方改动都还是比较大的。还有双方开发人员对于微服务的熟悉程度。所以我起初看到这个问题的时候,我反而还没有想用微服务的,因为从题主的描述来看,我感觉他更希望用一种结合
Spring
整合缓存,然后替换之前的工具包里的逻辑而已,这样相当于只是改了之前工具包里的逻辑,就算调用接口被改,调用方修改的代价也是比较小的,改改方法名和入参而已。因此我谈谈我自己的看法吧,我能想到的
Spring
整合缓存那肯定是Spring Cache
,Spring
作为一个整合框架,要的就是一招可以针对某个业务提出统一接口,然后第三方实现,相当于Spring
项目级别的SPI
,那对于Cache
来说,Spring
也有抽象有一套接口和注解,可以搜索直接Spring Cache
,简单了解一下用法即可回到题主的需求上,需要读数据库+
redis
+本地缓存,那其实我自己理解这应该就是本地缓存作为一级缓存,redis
作为二级缓存,最后再去读DB
那这跟
Spring Cache
的方法注解@Cacheable
就有类似的效果了@Cacheable
标注一个方法,提供缓存的name
,对应的key
,以及使用哪个CacheManager
处理,例如下面的例子一样如果这次操作的
CacheManager
返回为null
,那就执行方法all()
,并且方法all()
的值最后会被交给CacheManager
中的Cache
做处理缓存起来如上的描述其实基本就满足了题主的需求,只是有一点,题主是有两级缓存的,刚刚的描述好像没有提到,其实不然,我们来看
Spring
的CacheManager
的接口定义根据缓存的
name
返回一个Cache
,其实Cache
就是某种类型的缓存的抽象,比如有Redis
的实现RedisCache
,EhCache
的实现EhCacheCache
等等。但是

CacheManager
的定义是根据name
返回一个Cache
,也没有指定要什么类型的(虽然RedisCache
和EhCacheCache
都有他们自己的CacheManager
),所以CacheManager
管理的Cache
理论是可以有多不同类型的实现。当然不用题主定义,Spring
想好了,请看CompositeCacheManager
CompositeCacheManager
如其名,组合的CacheManager
,虽然有不同类型的Cache
实现,也有不同的CacheManager
类型实现,现在CompositeCacheManager
就可以把不同类型的CacheManager
合在一起,因为合在一起的方式是集合List<CacheManager>
,而集合是有顺序的,所以题主这下应该明白为啥可以实现两级缓存了叭,这就是我的想法那废话不多说,只要题主了解一下
Spring Cache
的相关知识,接下来我的做法应该可以理解了本地缓存我就以
EhCache
举例吧,我主要展示Cache
的配法,其他的配置就不展示了哈那我们先配置一个
EhCache
的CacheManager
:EhCacheCacheManager
接下来再配一个
Redis
的CacheManager
:RedisCacheManager
两个
CacheManager
都有了,关键的,我们再配置一个新的CacheManager
:CompositeCacheManager
注意上面的顺序哈,如果想要优先
EhCache
命中,当然EhCacheCacheManager
就要放在构造方法的参数中的最前面哈,并且为了@Cacheable
配置起来很简洁,我们加一个@Primary
,因为现在有三个CacheManager
了,这样的话,我们使用@Cacheable
就可以不用指定那个cacheManager
参数了其次,为了
CompositeCacheManager
和@Cacheable
能关联起来,我们需要配置一个CacheResolver
最后,就是如何使用了,假设对外提供了一个脏数据查询的接口
那它的实现可以这样写
非常简单哈,这其中的
cacheNames
中的EHCACHE_DIRTY_DATA
,是和你配置的EhCache
的名字一样哈,因为EhCache
的配置是xml
的,所以xml
里的名字要和这里一致至于
Redis
的REDIS_DIRTY_DATA
,这个可以随意了,毕竟没有的话,默认情况下,它是可以自己造一个的,参考RedisCacheManager
的getMissingCache
我把完整代码放到github上吧,我提供的方案只是我自己对于你描述的业务的理解,虽然不一定能解决你的问题,不过
Spring Cache
是你可以考虑的方向哈那就这样叭~拜了个拜(ˉ▽ ̄~)