Go-Java 互通示例

2022-04-14 15:01 更新

準(zhǔn)備工作

環(huán)境

JDK 8,Golang >= 1.15,Dubbo 3.0.2,zookeeper 啟動,

Go- Java 互通前提

  • Go/Java 定義的傳輸結(jié)構(gòu)一致
    PB 序列化
    proto for Go
    // The response message containing the greetings
    message User {
      string name = 1;
      string id = 2;
      int32 age = 3;
    }
    

    proto for Java

    // The response message containing the greetings
    message User {
      string name = 1;
      string id = 2;
      int32 age = 3;
    }
    Hessian 序列化
    POJO for Go,需參考 Dubbo-go Hessian 序列化支持文檔
    type User struct {
      ID   string
      Name string
      Age  int32
    }
    
    func (u *User) JavaClassName() string {
    	return "org.apache.dubbo.User"
    }
    
    func init(){
    	hessian.RegisterPOJO(&User{})  
    }
    

    POJO for Java

    package org.apache.dubbo
    
    public class User {
      private String id;
      private String name;
      private int age;
    }
  • Java 需要互通的方法簽名與 Go 一致
    例如:
    Java Interface
    public interface IGreeter {
      /**
       * <pre>
       *  Sends a greeting
       * </pre>
       */
    	User sayHello(HelloRequest request);
    }
    Go client (由protoc-gen-go-triple 根據(jù) proto 文件自動生成)
    type GreeterClientImpl struct {
    	// Sends a greeting
    	SayHello func(ctx context.Context, in *HelloRequest) (*User, error)
    }
    Go server (由開發(fā)者定義)
    type GreeterProvider struct {
    	api.GreeterProviderBase
    }
    
    func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
    	logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
    	return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
    }
    Go 方法需要遵守 Dubbo-go 3.0 用戶服務(wù)接口定義規(guī)范
  • Java 的三元組與Go service/reference 配置的 interface 一致
    三元組,即為接口級別配置的:interface, group, version。其中需要注意,group 和 version 的概念為 dubbo 接口的 group 和vesion,在啟動 dubbo-java 服務(wù)時配置于 spring cloud 的 properties 文件中,并非pom.xml 中 mvn 依賴的version。 
    group 和version 默認(rèn)為空,在 dubbo-go 框架中,可以在service/reference 的對應(yīng)位置指定 group 和 version。
    例如:
    Java 的接口全名:com.apache.dubbo.sample.basic.IGreeter,接口 version 為v1.0.1, group 為Go-client:
    references:
      GreeterClientImpl:
        protocol: tri
        interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
        group: dubbogo # 需要與服務(wù)端對應(yīng) 默認(rèn)為空
        version: v1.0.1 # 需要與服務(wù)端對應(yīng) 默認(rèn)為空
    

    Go-server:

    services:
      GreeterProvider:
        protocol-ids: tripleProtocol
        interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
        group: dubbogo # 需要與服務(wù)端對應(yīng) 默認(rèn)為空
        version: v1.0.1 # 需要與服務(wù)端對應(yīng) 默認(rèn)為空

1. 基于 Triple 協(xié)議互通 (PB序列化)

參考 dubbo-go-samples/helloworld

1.1 Go-Client -> Java-Server

Java-Server 啟動

  1. 定義 Java 的 PB 文件,可參考 Dubbo 快速開始
    syntax = "proto3";
    
    option java_package = "org.apache.dubbo.sample.hello";
    
    package helloworld;
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings
    message User {
      string name = 1;
      string id = 2;
      int32 age = 3;
    }
    

    該接口描述文件定義了將會生成的 Java 類 org.apache.dubbo.sample.hello.Helloworld,以及類中包含的傳輸結(jié)構(gòu) HelloRequest 和 User 類。

  2. 定義服務(wù)接口:com.apache.dubbo.sample.basic.IGreeter
    package com.apache.dubbo.sample.basic;
    
    // 引入根據(jù) PB 生成的類
    import org.apache.dubbo.sample.hello.Helloworld.User;
    import org.apache.dubbo.sample.hello.Helloworld.HelloRequest;
    
    public interface IGreeter {
        /**
         * <pre>
         *  Sends a greeting
         * </pre>
         */
      // 定義接口
    	User sayHello(HelloRequest request);
    }
    
  3. 實現(xiàn)服務(wù)接口:IGreeter1Impl.java
    package com.apache.dubbo.sample.basic;
    
    import org.apache.dubbo.sample.hello.Helloworld.User;
    import org.apache.dubbo.sample.hello.Helloworld.HelloRequest;
    
    public class IGreeter1Impl implements IGreeter {
        @Override
        public User sayHello(HelloRequest request) {
            System.out.println("receiv: " + request);
            User usr = User.newBuilder()
                    .setName("hello " + request.getName())
                    .setAge(18)
                    .setId("12345").build();
            return usr;
        }
    }
    
  4. 使用 Dubbo3 框架啟動服務(wù)ApiProvider.java
    package com.apache.dubbo.sample.basic;
    
    import org.apache.dubbo.common.constants.CommonConstants;
    import org.apache.dubbo.config.ApplicationConfig;
    import org.apache.dubbo.config.ProtocolConfig;
    import org.apache.dubbo.config.RegistryConfig;
    import org.apache.dubbo.config.ServiceConfig;
    import java.util.concurrent.CountDownLatch;
    
    public class ApiProvider {
        public static void main(String[] args) throws InterruptedException {
          ServiceConfig<IGreeter> service = new ServiceConfig<>();
          service.setInterface(IGreeter.class);
          service.setRef(new IGreeter1Impl());
          // 使用 Triple 協(xié)議
          service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051));
          service.setApplication(new ApplicationConfig("demo-provider"));
          // 使用 ZK 作為注冊中心
          service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
          service.export();
          System.out.println("dubbo service started");
          new CountDownLatch(1).await();
        }
    }
    

    啟動服務(wù),可看到輸出如下日志,代表 Java Triple Server 啟動成功

    main  INFO bootstrap.DubboBootstrap:  [DUBBO] DubboBootstrap has started., dubbo version: 3.0.2, current host: 192.168.0.108
    dubbo service started
    

Go-Client 啟動

對于已經(jīng)啟動的Dubbo服務(wù),如需要開發(fā)與其對應(yīng)的Go-client,需要進行如下步驟:

1.編寫與 Java 適配的 proto文件samples_api.proto

    
    syntax = "proto3";
    package api; // pacakge 名隨意指定
    
    // necessary
    option go_package = "./;api";
    
    // The greeting service definition.
    service Greeter {
      // Sends a greeting
      rpc SayHello (HelloRequest) returns (User) {}
    }
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings
    message User {
      string name = 1;
      string id = 2;
      int32 age = 3;
    }
    

    2.使用 protoc-gen-triple 生成接口文件

      protoc -I . samples_api.proto --triple_out=plugins=triple:.
      

      3.撰寫配置文件: dubbogo.yml

        dubbo:
          registries:
            demoZK:
              protocol: zookeeper
              address: 127.0.0.1:2181
          consumer:
            references:
              GreeterClientImpl:
                protocol: tri
                interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
        

        4.撰寫 main.go 文件,發(fā)起調(diào)用

          // 引入生成的接口結(jié)構(gòu)
          var grpcGreeterImpl = new(api.GreeterClientImpl)
          
          // export DUBBO_GO_CONFIG_PATH=dubbogo.yml
          func main() {
          	config.SetConsumerService(grpcGreeterImpl)
          	if err := config.Load(); err != nil {
          		panic(err)
          	}
          	time.Sleep(3 * time.Second)
          
          	logger.Info("start to test dubbo")
          	req := &api.HelloRequest{
          		Name: "laurence",
          	}
          	reply, err := grpcGreeterImpl.SayHello(context.Background(), req)
          	if err != nil {
          		logger.Error(err)
          	}
          	logger.Infof("client response result: %v\n", reply)
          }
          

          5.可查看到調(diào)用成功的日志

            • go-client
            cmd/client.go:53        client response result: name:"hello laurence" id:"12345" age:18 
            
            • java-server
            receiv: name: "laurence"
            

            1.2 Java-Client -> Go-Server

            Go-Server 啟動

            1.定義配置文件

              dubbo:
                registries:
                  demoZK:
                    protocol: zookeeper
                    address: 127.0.0.1:2181
                protocols:
                  triple:
                    name: tri
                    port: 20000
                provider:
                  services:
                    GreeterProvider:
                      interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java
              

              2.引入傳輸結(jié)構(gòu),定義服務(wù)

                type GreeterProvider struct {
                	api.GreeterProviderBase
                }
                
                func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) {
                	logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name)
                	return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil
                }
                

                3.啟動服務(wù)

                  // export DUBBO_GO_CONFIG_PATH=dubbogo.yml
                  func main() {
                  	config.SetProviderService(&GreeterProvider{})
                  	if err := config.Load(); err != nil {
                  		panic(err)
                  	}
                  	select {}
                  }
                  

                  Java-Client 啟動

                  1. proto 文件編寫和接口生成參考上述 java-server 介紹
                  2. 啟動ConsumerApiCnosumer.java
                  public class ApiConsumer {
                      public static void main(String[] args) throws InterruptedException, IOException {
                          ReferenceConfig<IGreeter> ref = new ReferenceConfig<>();
                          ref.setInterface(IGreeter.class);
                          ref.setCheck(false);
                          ref.setProtocol(CommonConstants.TRIPLE);
                          ref.setLazy(true);
                          ref.setTimeout(100000);
                          ref.setApplication(new ApplicationConfig("demo-consumer"));
                          ref.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
                          final IGreeter iGreeter = ref.get();
                  
                          System.out.println("dubbo ref started");
                          Helloworld.HelloRequest req = Helloworld.HelloRequest.newBuilder().setName("laurence").build();
                          try {
                              final Helloworld.User reply = iGreeter.sayHello(req);
                              TimeUnit.SECONDS.sleep(1);
                              System.out.println("Reply:" + reply);
                          } catch (Throwable t) {
                              t.printStackTrace();
                          }
                          System.in.read();
                      }
                  }
                  

                  2. 基于 Dubbo 協(xié)議互通 (Hessian2序列化)

                  參考 dubbo-go-samples/rpc/dubbo

                  2.1 Go-Client -> Java-Server

                  Java-Server 啟動

                  1.定義 Java 接口、參數(shù)和返回值,可參考 Dubbo 快速開始

                    package org.apache.dubbo;
                    
                    // 需要暴露的服務(wù)接口
                    public interface UserProvider {
                        User getUser(int usercode);
                    }
                    
                    package org.apache.dubbo;
                    
                    public class User implements Serializable  {
                    
                        private String id;
                    
                        private String name;
                    
                        private int age;
                    
                        private Date time = new Date();
                    		/* ... */
                    }
                    

                    2.實現(xiàn)服務(wù)接口:

                      UserProviderImpl.java

                      
                      package org.apache.dubbo;
                      public class UserProviderImpl implements UserProvider {
                          public User getUser(int userCode) {
                              return new User(String.valueOf(userCode), "userCode get", 48);
                          }
                      }
                      

                      3.使用SpringBoot 啟動

                        Provider.java

                        package org.apache.dubbo;
                        
                        // use when config by API
                        /* 
                        import java.util.concurrent.CountDownLatch;
                        
                        import org.apache.dubbo.common.constants.CommonConstants;
                        import org.apache.dubbo.config.ApplicationConfig;
                        import org.apache.dubbo.config.ProtocolConfig;
                        import org.apache.dubbo.config.RegistryConfig;
                        import org.apache.dubbo.config.ServiceConfig;
                        */
                        import org.springframework.context.support.ClassPathXmlApplicationContext;
                        
                        public class Provider {
                            // main function, config from spring boot
                            public static void main(String[] args) throws Exception {
                                ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.provider.xml"});
                                context.start();
                                System.in.read(); // press any key to exit
                            }
                        
                          
                        //    config by API
                        //    public static void startComplexService() throws InterruptedException {
                        //        ServiceConfig<ComplexProvider> service = new ServiceConfig<>();
                        //        service.setInterface(ComplexProvider.class);
                        //        service.setRef(new ComplexProviderImpl());
                        //        service.setProtocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, 20001));
                        //        service.setApplication(new ApplicationConfig("demo-provider"));
                        //        service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
                        //        service.export();
                        //        System.out.println("dubbo service started");
                        //        new CountDownLatch(1).await();
                        //    }
                        }
                        

                        4.通過Spring 配置 Dubbo 參數(shù)Resources/META-INF.spring/dubbo.provider.xml

                          <?xml version="1.0" encoding="UTF-8"?>
                          <!--
                            Licensed under the Apache License, Version 2.0 (the "License");
                            you may not use this file except in compliance with the License.
                            You may obtain a copy of the License at
                          
                                 http://www.apache.org/licenses/LICENSE-2.0
                          
                            Unless required by applicable law or agreed to in writing, software
                            distributed under the License is distributed on an "AS IS" BASIS,
                            WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                            See the License for the specific language governing permissions and
                            limitations under the License.
                          -->
                          
                          <beans xmlns="http://www.springframework.org/schema/beans"
                          	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                          	   xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
                          	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                          	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
                          
                          	<!-- 應(yīng)用名 -->
                          	<dubbo:application name="user-info-server"/>
                          	<!-- 連接到哪個本地注冊中心 -->
                          	<dubbo:registry id="dubbogo"  address="zookeeper://127.0.0.1:2181" />
                          	<!-- 用dubbo協(xié)議在20880端口暴露服務(wù) -->
                          	<dubbo:protocol id="dubbo" name="dubbo" host="127.0.0.1" port="20010" />
                          	<!-- 聲明需要暴露的服務(wù)接口 -->
                          	<dubbo:service id="aaa" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="demoService"/>
                          	<dubbo:service id="bbb" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="otherService" version="2.0"/>
                          	<dubbo:service id="ccc" registry="dubbogo" timeout="3000" interface="org.apache.dubbo.UserProvider" ref="otherService" group="as" version="2.0"/>
                          
                          	<bean id="demoService" class="org.apache.dubbo.UserProviderImpl" />
                          	<bean id="otherService" class="org.apache.dubbo.UserProviderAnotherImpl"/>
                          
                          </beans>
                          

                          啟動Provider類,可看到輸出如下日志,代表 Dubbo Server 啟動成功

                          [DUBBO] DubboBootstrap is ready., dubbo version: 2.7.7, current host: 127.0.0.1
                          [DUBBO] DubboBootstrap has started., dubbo version: 2.7.7, current host: 127.0.0.1
                          

                          Go-Client 啟動

                          對于已經(jīng)啟動的Dubbo服務(wù),如需要開發(fā)與其對應(yīng)的Go-client,需要進行如下步驟:

                          1.編寫與 Java 適配的 POJO 類 User

                            import(
                              hessian "github.com/apache/dubbo-go-hessian2"
                            )
                            
                            // 字段需要與 Java 側(cè)對應(yīng),首字母大寫
                            type User struct {
                            	ID   string
                            	Name string
                            	Age  int32
                            	Time time.Time
                            }
                            
                            
                            func (u *User) JavaClassName() string {
                            	return "org.apache.dubbo.User" // 需要與 Java 側(cè) User 類名對應(yīng)
                            }
                            
                            func init(){
                            	hessian.RegisterPOJO(&pkg.User{}) // 注冊 POJO
                            }
                            

                            2.編寫與 Java 側(cè)一致的客戶端存根類,其接口方法需要與Java側(cè)對應(yīng)規(guī)定第一個參數(shù)必須為 context.Context,最后一個返回值必須為 error

                              import(
                              	"dubbo.apache.org/dubbo-go/v3/config"
                              )
                              
                              var (
                              	userProvider = &pkg.UserProvider{}
                              )
                              
                              // UserProvider 客戶端存根類
                              type UserProvider struct {
                                // dubbo標(biāo)簽,用于適配go側(cè)客戶端大寫方法名 -> java側(cè)小寫方法名,只有 dubbo 協(xié)議客戶端才需要使用
                              	GetUser  func(ctx context.Context, req int32) (*User, error) `dubbo:"getUser"` 
                              }
                              
                              func init(){
                                // 注冊客戶端存根類到框架,實例化客戶端接口指針 userProvider
                              	config.SetConsumerService(userProvider)
                              }
                              

                              3.撰寫配置文件: dubbogo.yml

                                dubbo:
                                  registries:
                                    demoZK: # 定義注冊中心ID
                                      protocol: zookeeper
                                      timeout: 3s
                                      address: 127.0.0.1:2181
                                  consumer:
                                    references:
                                      UserProvider: # 存根類名
                                        protocol: dubbo # dubbo 協(xié)議,默認(rèn) hessian2 序列化方式
                                        interface: org.apache.dubbo.UserProvider # 接口需要與Java側(cè)對應(yīng)
                                  logger:
                                    zap-config:
                                      level: info # 日志級別
                                

                                或者使用Triple + Hessian2 序列化請求Server。本例子如果跟Java Server互通則不能用Triple。

                                dubbo:
                                  registries:
                                    demoZK:
                                      protocol: zookeeper
                                      timeout: 3s
                                      address: 127.0.0.1:2181
                                  consumer:
                                    references:
                                      UserProvider: 
                                        protocol: tri # triple 協(xié)議
                                        serialization: hessian2 # 序列化方式 hessian2,triple 協(xié)議默認(rèn)為 pb 序列化,不配置會報錯
                                        interface: org.apache.dubbo.UserProvider 
                                  logger:
                                    zap-config:
                                      level: info
                                

                                4.撰寫 main.go 文件,發(fā)起調(diào)用

                                  func main(){
                                    config.Load()
                                  	var i int32 = 1
                                  	user, err := userProvider.GetUser2(context.TODO(), i)
                                  	if err != nil {
                                  		panic(err)
                                  	}
                                  	logger.Infof("response result: %v", user)
                                  }
                                  

                                  5.可查看到調(diào)用成功的日志,符合預(yù)期

                                    • go-client
                                    response result: User{ID:1, Name:userCode get, Age:48, Time:2021-10-21 20:25:26.009 +0800 CST}
                                    

                                    2.2 Java-Client -> Go-Server

                                    Go-Server 啟動

                                    1.定義配置文件

                                      dubbo:
                                        registries:
                                          demoZK:
                                            protocol: zookeeper
                                            address: 127.0.0.1:2181
                                        protocols:
                                          dubbo:
                                            name: dubbo
                                            port: 20000
                                        provider:
                                          services:
                                            UserProvider:
                                              interface: org.apache.dubbo.UserProvider
                                        logger:
                                          zap-config:
                                            level: info
                                      

                                      2.引入傳輸結(jié)構(gòu),定義服務(wù)以及方法名映射

                                      type UserProvider struct {
                                      }
                                      
                                      func (u *UserProvider) GetUser(ctx context.Context, req int32) (*User, error) {
                                      	var err error
                                      	logger.Infof("req:%#v", req)
                                      	user := &User{}
                                      	user.ID = strconv.Itoa(int(req))
                                      	return user, err
                                      }
                                      
                                      // MethodMapper 定義方法名映射,從 Go 的方法名映射到 Java 小寫方法名,只有 dubbo 協(xié)議服務(wù)接口才需要使用
                                      func (s *UserProvider) MethodMapper() map[string]string {
                                      	return map[string]string{
                                      		"GetUser": "getUser",
                                      	}
                                      }
                                      
                                      func init(){
                                        config.SetProviderService(&pkg.UserProvider{})
                                      }
                                      

                                      3.啟動服務(wù)

                                        // export DUBBO_GO_CONFIG_PATH=dubbogo.yml
                                        func main() {
                                        	if err := config.Load(); err != nil {
                                        		panic(err)
                                        	}
                                        	select {}
                                        }
                                        

                                        Java-Client 啟動

                                        1.Java 客戶端 Spring 配置

                                        resources/META-INF.spring/dubbo.consumer.xml<?xml version="1.0" encoding="UTF-8"?>

                                        <!--
                                          Licensed under the Apache License, Version 2.0 (the "License");
                                          you may not use this file except in compliance with the License.
                                          You may obtain a copy of the License at
                                        
                                               http://www.apache.org/licenses/LICENSE-2.0
                                        
                                          Unless required by applicable law or agreed to in writing, software
                                          distributed under the License is distributed on an "AS IS" BASIS,
                                          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                                          See the License for the specific language governing permissions and
                                          limitations under the License.
                                        -->
                                        <beans xmlns="http://www.springframework.org/schema/beans"
                                        	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                        	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
                                        	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                                        	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
                                        
                                        
                                        	<!-- 消費方應(yīng)用名,用于計算依賴關(guān)系,不是匹配條件,不要與提供方一樣 -->
                                        	<dubbo:application name="user-info-client" />
                                        	<!-- 連接到哪個本地注冊中心 -->
                                        	<dubbo:registry id="dubbogo"  address="zookeeper://127.0.0.1:2181" />
                                        	<!-- dubbo.registry.address from dubbo.properties -->
                                        	<!-- dubbo:registry address="${dubbo.registry.address}" / -->
                                        
                                        	<!-- 用dubbo協(xié)議在20880端口暴露服務(wù) -->
                                        	<dubbo:protocol id="dubbo" name="dubbo" />
                                        
                                        	<!-- 聲明需要使用的服務(wù)接口 -->
                                        	<dubbo:reference registry="dubbogo" check="false" id="userProvider" protocol="dubbo" interface="org.apache.dubbo.UserProvider">
                                        		<!--<dubbo:parameter key="heartbeat" value="10000"/ -->
                                            </dubbo:reference>
                                        
                                        	<dubbo:reference registry="dubbogo" check="false" id="userProvider1" protocol="dubbo" version="2.0" interface="org.apache.dubbo.UserProvider">
                                        	</dubbo:reference>
                                        	<dubbo:reference registry="dubbogo" check="false" id="userProvider2" protocol="dubbo" version="2.0" group="as" interface="org.apache.dubbo.UserProvider">
                                        	</dubbo:reference>
                                        </beans>

                                        2.發(fā)起調(diào)用

                                        public class Consumer {
                                            // Define a private variable (Required in Spring)
                                            private static UserProvider userProvider;
                                        
                                            public static void main(String[] args) throws Exception {
                                                ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.consumer.xml"});
                                                userProvider = (UserProvider)context.getBean("userProvider");
                                                testGetUser();
                                            }
                                          
                                         
                                            private static void testGetUser() throws Exception {
                                                User user = userProvider.getUser(1);
                                                System.out.println(user.getId());
                                            }
                                        }
                                        



                                        以上內(nèi)容是否對您有幫助:
                                        在線筆記
                                        App下載
                                        App下載

                                        掃描二維碼

                                        下載編程獅App

                                        公眾號
                                        微信公眾號

                                        編程獅公眾號