欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Spring Cloud 跨服务数据聚合框架

程序员文章站 2022-03-25 15:03:01
ag-merge spring cloud 跨服务数据聚合框架 解决问题 解决spring cloud服务拆分后分页数据的属性或单个对象的属性拆分之痛, 支持对静态数...

ag-merge

spring cloud 跨服务数据聚合框架

解决问题

解决spring cloud服务拆分后分页数据的属性或单个对象的属性拆分之痛, 支持对静态数据属性(数据字典)、动态主键数据进行自动注入和转化, 其中聚合的静态数据会进行 一级混存 (guava).

举个栗子:

两个服务,a服务的某张表用到了b服务的某张表的值,我们在对a服务那张表查询的时候,把b服务某张表的值聚合在a服务的那次查询过程中

示例

具体示例代码可以看 ace-merge-demo 模块

|------- ace-eureka 注册中心
|------- ace-data-merge-demo 查询数据,此处聚合示例
|------- ace-data-provider 数据提供者

maven添加依赖

<dependency>
  <groupid>com.github.wxiaoqi</groupid>
  <artifactid>ace-merge-core</artifactid>
  <version>2.0-snapshot</version>
</dependency>

推荐仓库配置

<repositories>
    <repository>
      <id>oss</id>
      <name>oss</name>
      <url>https://oss.sonatype.org/content/groups/public</url>
    </repository>
  </repositories>

启动类加注解

@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 @interface mergefield {
  /**
   * 查询值
   * @return
   */
  string key() default "";

  /**
   * 目标类
   * @return
   */
  class<? extends object> feign() default object.class;

  /**
   * 调用方法
   * @return
   */
  string method() default "";

  /**
   * 是否以属性值合并作为查询值
   * @return
   */
  boolean isvalueneedmerge() default false;
}

聚合对象

public class user {
  private string name;
  // 需要聚合的属性
  @mergefield(key="test", feign = iservice2.class,method = "writelog")
  private string sex;
  // 需要聚合的属性
  @mergefield(feign = iservice2.class,method = "getcitys",isvalueneedmerge = true)
  private string city;

  public user(string name, string sex, string city) {
    this.name = name;
    this.sex = sex;
    this.city = city;
  }

  public string getcity() {
    return city;
  }

  public void setcity(string city) {
    this.city = city;
  }

  public user(string name) {
    this.name = name;
  }

  public user(string name, string sex) {
    this.name = name;
    this.sex = sex;
  }

  public string getname() {
    return name;
  }

  public void setname(string name) {
    this.name = name;
  }

  public string getsex() {
    return sex;
  }

  public void setsex(string sex) {
    this.sex = sex;
  }
}

聚合数据来源方法(示例为通过feignclient,也可以是本地的spring bean对象)

特别要求:入参必须为一个string,返回值必须为map<string,string>. 其中返回值的构成,就是聚合对象属性的key和对应的value.

@feignclient("test")
public interface iservice2 {
  @requestmapping("car/do")
  public map<string, string> writelog(string test);

  @requestmapping("car/city")
  public map<string, string> getcitys(string ids);
}

对应的远程服务接口

/**
 * @author ace
 * @create 2017/11/20.
 */
@restcontroller
@requestmapping("car")
public class service2rest {
  private logger logger = loggerfactory.getlogger(service2rest.class);

  @requestmapping("do")
  public map<string,string> writelog(string test){
    logger.info("service 2 is writing log!");
    map<string,string> map = new hashmap<string, string>();
    map.put("man","男");
    map.put("woman","女");
    return map;
  }

  @requestmapping("city")
  public map<string,string> getcity(string ids){
    logger.info("service 2 is writing log!"+ids);
    map<string,string> map = new hashmap<string, string>();
    map.put("1","广州");
    map.put("2","武汉");
    return map;
  }
}

聚合对象的biz类(下面的方式是采用aop扫描注解的方式)

@service
@slf4j
public class userbiz {
  @autowired
  private mergecore mergecore;
  /**
   *   aop注解的聚合方式
   *   其中聚合的方法返回值必须为list,
   *   如果为复杂对象,则需要自定义自己的聚合解析器(实现接口imergeresultparser)
   */
  @mergeresult(resultparser = testmergeresultparser.class)
  public list<user> getaopuser() {
    arraylist<user> users = new arraylist<user>();
    for (int i = 1000; i > 0; i--) {
      users.add(new user("zhangsan" + i, "man", "1"));
      users.add(new user("lisi" + i, "woman", "2"));
      users.add(new user("wangwu" + i, "unkonwn", "2"));
    }
    return users;
  }

  /**
   * 手动聚合方式
   * @return
   */
  public list<user> getuser(){
    arraylist<user> users = new arraylist<user>();
    for (int i = 1000; i > 0; i--) {
      users.add(new user("zhangsan" + i, "man", "1"));
      users.add(new user("lisi" + i, "woman", "2"));
      users.add(new user("wangwu" + i, "unkonwn", "2"));
    }
    try {
      // list 聚合
      mergecore.mergeresult(user.class,users);
      // 单个对象聚合
//      mergecore.mergeone(user.class,users.get(0));
    } catch (exception e) {
      log.error("数据聚合失败",e);
    }finally {
      return users;
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。