dubbo實現動態調用


在支付網關的業務中,在用戶支付成功/失敗后需要異步通知業務方,這個時候業務方是一個變數,支付網關可以定義一個interface,各個業務方來實現這個接口。

支付網關配置一個回調配置表,表中包含:group、ZK的注冊地址等dubbo調用必須要的參數值。

dubbo在ZK上的注冊信息示例:

dubbo://192.168.18.234:20883/com.wy.payment.service.CutPaymentService?anyhost=true&application=installment&default.timeout=30000&dubbo=2.5.3&interface=com.wy.payment.service.CutPaymentService&methods=updateRepaymentPlan,updatePaymentOrderStatus,selectOrderByCondition,createRepaymentPlan,selectPayWaterByBid,cutPayment&pid=31913&revision=0.0.1-SNAPSHOT&side=provider&timestamp=1489374649211

 

動手開干,先建配置表。

 1 CREATE TABLE `pay_callback_config` (
 2   `id` bigint(20) NOT NULL AUTO_INCREMENT,
 3   `system_id` varchar(20) DEFAULT NULL COMMENT '業務系統標識',
 4   `registry_address` varchar(100) DEFAULT NULL COMMENT 'zk注冊地址',
 5   `registry_group` varchar(50) DEFAULT NULL COMMENT 'zk注冊組',
 6   `registry_version` varchar(20) DEFAULT NULL COMMENT '服務的版本號',
 7   `valid_flag` tinyint(1) DEFAULT '1' COMMENT '是否有效,1有效 0無效',
 8   `create_date` datetime DEFAULT NULL COMMENT '創建時間',
 9   PRIMARY KEY (`id`)
10 ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='支付回調的配置表';

對應的domain類:

 1 package xxx.domain;
 2 
 3 import java.io.Serializable;
 4 import java.util.Date;
 5 
 6 import xxx.PaymentConstants;
 7 
 8 import lombok.Data;
 9 
10 /**
11  * 支付回調的相關配置 對應表:pay_callback_config
12  * 
13  * @author yangzhilong
14  *
15  */
16 @Data
17 public class PayCallbackConfig implements Serializable{
18     /**
19      * 
20      */
21     private static final long serialVersionUID = 339298526553679045L;
22     
23     private Long id;
24     /**
25      * 業務系統標識 {@link PaymentConstants.BUSINESS_SYSTEM}
26      */
27     private String systemId;
28     /**
29      * zk注冊地址
30      */
31     private String registryAddress;
32     /**
33      * zk注冊組
34      */
35     private String registryGroup;
36     /**
37      * 服務的版本號
38      */
39     private String registryVersion;
40     /**
41      * 有效標識
42      */
43     private Boolean validFlag;
44     /**
45      * 創建時間
46      */
47     private Date createDate; 
48 }

Spring Boot的配置類:

 1 package xx.configuration;
 2 
 3 import java.util.List;
 4 
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 7 import org.springframework.context.annotation.Bean;
 8 import org.springframework.context.annotation.Configuration;
 9 
10 import xx.domain.PayCallbackConfig;
11 import xx.mapper.PayCallbackConfigMapper;
12 import xx.utils.PayCallbackUtils;
13 import xx.utils.UselessBean;
14 
15 /**
16  * 支付回調的初始化代碼
17  * 
18  * @author yangzhilong
19  *
20  */
21 @Configuration
22 @ConditionalOnClass(PayCallbackConfigMapper.class)
23 public class PayCallbackConfiguration {
24     @Autowired
25     private PayCallbackConfigMapper payCallbackConfigMapper;
26 
27     @Bean
28     UselessBean uselessBean(){
29         List<PayCallbackConfig> list = payCallbackConfigMapper.listAllVaild();
30         if(null != list && !list.isEmpty()){
31             for(PayCallbackConfig item : list){
32                 PayCallbackUtils.init(item.getSystemId(), item.getRegistryAddress(), item.getRegistryGroup(), item.getRegistryVersion());
33             }
34         }
35         UselessBean uselessBean = new UselessBean();
36         return uselessBean;
37     }
38     
39 }

其中UselessBean就是一個空的類,定義這個就是利用spring對該類的初始來幫我初始化PayCallbackUtils類。

package xx.utils;

/**
 * 不會用的一個bean,只是用來在@Configuration幫忙初始化PayCallbackUtils的數據
 * 
 * @author yangzhilong
 *
 */
public class UselessBean {

}

真正的核心類:PayCallbackUtils

  1 package xx.utils;
  2 
  3 import java.util.Map;
  4 import java.util.concurrent.ConcurrentHashMap;
  5 
  6 import com.alibaba.dubbo.config.ApplicationConfig;
  7 import com.alibaba.dubbo.config.ReferenceConfig;
  8 import com.alibaba.dubbo.config.RegistryConfig;
  9 import xx.api.payment.HuaPayCallbackService;
 10 import xx.dto.payment.HuapayCallbackDTO;
 11 
 12 public class PayCallbackUtils {
 13     // 當前應用的信息
 14     private static ApplicationConfig application = new ApplicationConfig();
 15     // 注冊中心信息緩存
 16     private static Map<String, RegistryConfig> registryConfigCache = new ConcurrentHashMap<>();
 17     // 各個業務方的ReferenceConfig緩存
 18     private static Map<String, ReferenceConfig<HuaPayCallbackService>> referenceCache = new ConcurrentHashMap<>();
 19 
 20     static {
 21         application.setName("test");
 22     }
 23 
 24     /**
 25      * 獲取注冊中心信息
 26      * 
 27      * @param address
 28      *            zk注冊地址
 29      * @param group
 30      *            dubbo服務所在的組
 31      * @return
 32      */
 33     private static RegistryConfig getRegistryConfig(String address, String group, String version) {
 34         String key = address + "-" + group + "-" + version;
 35         RegistryConfig registryConfig = registryConfigCache.get(key);
 36         if (null == registryConfig) {
 37             registryConfig = new RegistryConfig();
 38             registryConfig.setAddress(address);
 39             registryConfig.setGroup(group);
 40 
 41             registryConfigCache.put(key, registryConfig);
 42         }
 43         return registryConfig;
 44     }
 45 
 46     /**
 47      * 獲取服務的代理對象
 48      * 
 49      * @param business
 50      * @param address
 51      * @param group
 52      * @return
 53      */
 54     private static ReferenceConfig<HuaPayCallbackService> getReferenceConfig(String business, String address,
 55             String group, String version) {
 56         String referenceKey = business;
 57         ReferenceConfig<HuaPayCallbackService> referenceConfig = referenceCache.get(referenceKey);
 58         if (null == referenceConfig) {
 59             referenceConfig = new ReferenceConfig<>();
 60             referenceConfig.setApplication(application);
 61             referenceConfig.setRegistry(getRegistryConfig(address, group, version));
 62             referenceConfig.setInterface(HuaPayCallbackService.class);
 63             referenceConfig.setVersion(version);
 64 
 65             referenceCache.put(referenceKey, referenceConfig);
 66         }
 67         return referenceConfig;
 68     }
 69 
 70     /**
 71      * 初始化數據
 72      * 
 73      * @param business
 74      * @param address
 75      * @param group
 76      * @param version
 77      */
 78     public static void init(String business, String address, String group, String version) {
 79         getReferenceConfig(business, address, group, version);
 80     }
 81 
 82     /**
 83      * 調用遠程服務
 84      * 
 85      * @param business
 86      * @param address
 87      * @param group
 88      * @param version
 89      * @return
 90      */
 91     public static boolean invoke(String business, PayCallbackDTO dto) {
 92         ReferenceConfig<PayCallbackService> reference = getReferenceConfig(business, null, null, null);
 93         if (null != reference) {
 94             PayCallbackService callbackService = reference.get();
 95             if (null != callbackService) {
 96                 return callbackService.callback(dto);
 97             }
 98         }
 99         return false;
100     }
101 }

其中HuaPayCallbackService是我定義的支付回調的接口定義,業務系統的回調服務必須實現我這個接口。

示例代碼如下:

 1 package xx.api.payment;
 2 
 3 import xx.dto.payment.PayCallbackDTO;
 4 
 5 /**
 6  * 支付異步回調統一的接口
 7  * 
 8  * @author yangzhilong
 9  *
10  */
11 public interface PayCallbackService {
12     /**
13      * 回調的接口
14      * 
15      * @param callbackDTO
16      * @return 成功我就不會再回調,失敗我會有重試的機制
17      */
18     boolean callback(HuapayCallbackDTO callbackDTO);
19 }

回調參數的DTO:

package xx.gateway.dto.payment;

import java.io.Serializable;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = false)
public class PayCallbackDTO implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = -3475086707314113975L;
    /**
     * 支付狀態  {@link xx.PaymentConstants.PAY_STATUS}
     */
    private String payStatus;
    /**
     * 支付失敗的原因
     */
    private String payErrorInfo;
    /**
     * 業務系統訂單id
     */
    private String businessOrderId;
    /**
     * 支付流水id
     */
    private String payFlowId;
    /**
     * 支付渠道返回的code
     */
    private String channelRetCode;
    /**
     * 金額,單位:元
     */
    private String money;
}

 

本文參考DUBBO官方文檔實現:http://dubbo.io/API+Config-zh.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM