详解Spring Cloud 跨服务数据聚合框架
AG-Merge
SpringCloud跨服务数据聚合框架
解决问题
解决SpringCloud服务拆分后分页数据的属性或单个对象的属性拆分之痛,支持对静态数据属性(数据字典)、动态主键数据进行自动注入和转化,其中聚合的静态数据会进行一级混存(guava).
举个栗子:
两个服务,A服务的某张表用到了B服务的某张表的值,我们在对A服务那张表查询的时候,把B服务某张表的值聚合在A服务的那次查询过程中
示例
具体示例代码可以看ace-merge-demo模块
|-------ace-eureka注册中心 |-------ace-data-merge-demo查询数据,此处聚合示例 |-------ace-data-provider数据提供者
Maven添加依赖
com.github.wxiaoqi ace-merge-core 2.0-SNAPSHOT
推荐仓库配置
oss oss https://oss.sonatype.org/content/groups/public
启动类加注解
@EnableAceMerge
application.yml配置
#跨服务数据合并 merge: enabled:true guavaCacheNumMaxSize:1000 guavaCacheRefreshWriteTime:10#min guavaCacheRefreshThreadPoolSize:10 aop:#启动注解的方式,自动聚合 enabled:true
代码示例(@MergeField标志对象的数据需要聚合)
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
public@interfaceMergeField{
/**
*查询值
*@return
*/
Stringkey()default"";
/**
*目标类
*@return
*/
Classfeign()defaultObject.class;
/**
*调用方法
*@return
*/
Stringmethod()default"";
/**
*是否以属性值合并作为查询值
*@return
*/
booleanisValueNeedMerge()defaultfalse;
}
聚合对象
publicclassUser{
privateStringname;
//需要聚合的属性
@MergeField(key="test",feign=IService2.class,method="writeLog")
privateStringsex;
//需要聚合的属性
@MergeField(feign=IService2.class,method="getCitys",isValueNeedMerge=true)
privateStringcity;
publicUser(Stringname,Stringsex,Stringcity){
this.name=name;
this.sex=sex;
this.city=city;
}
publicStringgetCity(){
returncity;
}
publicvoidsetCity(Stringcity){
this.city=city;
}
publicUser(Stringname){
this.name=name;
}
publicUser(Stringname,Stringsex){
this.name=name;
this.sex=sex;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetSex(){
returnsex;
}
publicvoidsetSex(Stringsex){
this.sex=sex;
}
}
聚合数据来源方法(示例为通过FeignClient,也可以是本地的springbean对象)
特别要求:入参必须为一个String,返回值必须为Map
@FeignClient("test")
publicinterfaceIService2{
@RequestMapping("car/do")
publicMapwriteLog(Stringtest);
@RequestMapping("car/city")
publicMapgetCitys(Stringids);
}
对应的远程服务接口
/**
*@authorace
*@create2017/11/20.
*/
@RestController
@RequestMapping("car")
publicclassService2Rest{
privateLoggerlogger=LoggerFactory.getLogger(Service2Rest.class);
@RequestMapping("do")
publicMapwriteLog(Stringtest){
logger.info("service2iswritinglog!");
Mapmap=newHashMap();
map.put("man","男");
map.put("woman","女");
returnmap;
}
@RequestMapping("city")
publicMapgetCity(Stringids){
logger.info("service2iswritinglog!"+ids);
Mapmap=newHashMap();
map.put("1","广州");
map.put("2","武汉");
returnmap;
}
}
聚合对象的Biz类(下面的方式是采用aop扫描注解的方式)
@Service
@Slf4j
publicclassUserBiz{
@Autowired
privateMergeCoremergeCore;
/**
*aop注解的聚合方式
*其中聚合的方法返回值必须为list,
*如果为复杂对象,则需要自定义自己的聚合解析器(实现接口IMergeResultParser)
*/
@MergeResult(resultParser=TestMergeResultParser.class)
publicListgetAopUser(){
ArrayListusers=newArrayList();
for(inti=1000;i>0;i--){
users.add(newUser("zhangsan"+i,"man","1"));
users.add(newUser("lisi"+i,"woman","2"));
users.add(newUser("wangwu"+i,"unkonwn","2"));
}
returnusers;
}
/**
*手动聚合方式
*@return
*/
publicListgetUser(){
ArrayListusers=newArrayList();
for(inti=1000;i>0;i--){
users.add(newUser("zhangsan"+i,"man","1"));
users.add(newUser("lisi"+i,"woman","2"));
users.add(newUser("wangwu"+i,"unkonwn","2"));
}
try{
//list聚合
mergeCore.mergeResult(User.class,users);
//单个对象聚合
//mergeCore.mergeOne(User.class,users.get(0));
}catch(Exceptione){
log.error("数据聚合失败",e);
}finally{
returnusers;
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。