AG-Merge
Spring Cloud 跨服務數據聚合框架
解決問題
解決Spring Cloud服務拆分后分頁數據的屬性或單個對象的屬性拆分之痛, 支持對靜態數據屬性(數據字典)、動態主鍵數據進行自動注入和轉化, 其中聚合的靜態數據會進行 一級混存 (guava).
舉個栗子:
兩個服務,A服務的某張表用到了B服務的某張表的值,我們在對A服務那張表查詢的時候,把B服務某張表的值聚合在A服務的那次查詢過程中
示例
具體示例代碼可以看 ace-merge-demo 模塊
1
2
3
|
|------- ace-eureka 注冊中心 |------- ace-data-merge-demo 查詢數據,此處聚合示例 |------- ace-data-provider 數據提供者 |
Maven添加依賴
1
2
3
4
5
|
< dependency > < groupId >com.github.wxiaoqi</ groupId > < artifactId >ace-merge-core</ artifactId > < version >2.0-SNAPSHOT</ version > </ dependency > |
推薦倉庫配置
1
2
3
4
5
6
7
|
< repositories > < repository > < id >oss</ id > < name >oss</ name > < url >https://oss.sonatype.org/content/groups/public</ url > </ repository > </ repositories > |
啟動類加注解
1
|
@EnableAceMerge |
application.yml配置
1
2
3
4
5
6
7
8
|
# 跨服務數據合并 merge: enabled: true guavaCacheNumMaxSize: 1000 guavaCacheRefreshWriteTime: 10 # min guavaCacheRefreshThreadPoolSize: 10 aop: # 啟動注解的方式,自動聚合 enabled: true |
代碼示例( @MergeField 標志對象的數據需要聚合)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
@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 ; } |
聚合對象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
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.
1
2
3
4
5
6
7
8
|
@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); } |
對應的遠程服務接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/** * @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掃描注解的方式)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
@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; } } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://gitee.com/geek_qi/AG-Merge