This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-docs.git
commit b1331409c20e1914befcd1d4bc4ddd035b7f87cd Author: DeanLee <[email protected]> AuthorDate: Tue Aug 21 17:40:44 2018 +0800 update java-chassis-reference/en_US/build-consumer/develop-consumer-using-rpc.md --- .../build-consumer/develop-consumer-using-rpc.md | 105 +++++++++++++++------ 1 file changed, 74 insertions(+), 31 deletions(-) diff --git a/java-chassis-reference/en_US/build-consumer/develop-consumer-using-rpc.md b/java-chassis-reference/en_US/build-consumer/develop-consumer-using-rpc.md index b308390..1c84295 100644 --- a/java-chassis-reference/en_US/build-consumer/develop-consumer-using-rpc.md +++ b/java-chassis-reference/en_US/build-consumer/develop-consumer-using-rpc.md @@ -1,47 +1,90 @@ -# 使用透明RPC方式开发服务消费者 +--- +title: "Develop with RPC" +lang: en +ref: develop-with-rpc +permalink: /users/develop-with-rpc/ +excerpt: "Develop with RPC" +last_modified_at: 2017-08-15T15:01:43-04:00 +redirect_from: + - /theme-setup/ +--- -## 概念阐述 +{% include toc %} +## Concept Description -透明RPC开发模式允许用户通过简单的java interface像本地调用一样进行服务调用。 -透明RPC仅仅是一种开发模式: -* 与使用highway还是RESTful传输没有关联 -* 与producer使用透明RPC/Jax-RS还是SpringMVC模式开发没有关联 -* 也与producer代码是否实现这个interface没有关联。 - -透明RPC开发模式与spring cloud的feign类似,不过更简单,因为不必在这个interface中增加任何RESTful annotation。 +The RPC development mode allows you to add annotations on the microservice APIs to generate the service provider agent. In this case, you can call microservices. + +## Sample Code + +To call a microservice, you only need to declare a member of a service API type and add the @RpcReference annotation for the member, the microservice that depends on the declaration, and the schemaID. The sample code is as follows. -## 在spring bean中通过@RpcReference声明 ```java +import org.springframework.stereotype.Component; + +import org.apache.servicecomb.foundation.common.utils.BeanUtils; +import org.apache.servicecomb.foundation.common.utils.Log4jUtils; +import org.apache.servicecomb.provider.pojo.RpcReference; +import org.apache.servicecomb.samples.common.schema.Hello; +import org.apache.servicecomb.samples.common.schema.models.Person; + @Component -public class SomeBean { - ...... - - @RpcReference(microserviceName = "helloService", schemaId = "helloSchema") - private Hello hello; - - ...... +public class CodeFirstConsumerMain { + @RpcReference(microserviceName = "codefirst", schemaId = "codeFirstHello") + private static Hello hello; + + public static void main(String[] args) throws Exception { + init(); + System.out.println(hello.sayHi("Java Chassis")); + Person person = new Person(); + person.setName("ServiceComb/Java Chassis"); + System.out.println(hello.sayHello(person)); + } + + public static void init() throws Exception { + Log4jUtils.init(); + BeanUtils.init(); + } } ``` -## 脱离spring bean,直接通过api声明 + +In the preceding code, the microservice consumers have obtained the microservice API Hello of the microservice provider and declared a member of the Hello type. The annotation `@RPCReference` on `Hello` specifies the microservice name and schemaId, The ServiceComb framework can obtain information about isntances from a certain provider during program startup and generate an agent to insert to Hello. This allows you to call a remote service in the same way as you call a local class. + +### Additional explanation for consumer invocation +In above example, in order to direct use `hello` in main function, we mark it as `static`. As a local field of `CodeFirstConsumerMain`, we recommend get it use these two way : + +#### First way: define cse:rpc-reference +In your bean.xml, add `cse:rpc-reference` configuration: + +```xml +<cse:rpc-reference id="hello" microservice-name="codefirst" + schema-id="codeFirstHello" interface="org.apache.servicecomb.samples.common.schema.Hello"></cse:rpc-reference> +``` + +Then use `BeanUtils.getBean` to get `Hello` provider: + ```java -Hello hello = Invoker.createProxy("helloService", "helloSchema", Hello.class); +Hello hello = BeanUtils.getBean("hello"); ``` -## reactive -只需要使用jdk的CompletableFuture对返回值进行包装即可 +#### Second way: get Bean, then use field +First use `BeanUtils.getBean` to get Bean of `CodeFirstConsumerMain`: + ```java -interface Hello { - CompletableFuture<String> sayHi(String name); -} +//Default instance name of Spring Bean is same as class name with first char low-cased +CodeFirstConsumerMain consumer = BeanUtils.getBean("codeFirstConsumerMain"); ``` -同一个interface中,可以同时声明同一个方法的reactive和同步原型 -因为要求方法名与契约中的operationId一一对应,而仅有返回值类型不同,在java中是非法的,所以需要修改方法名,并通过swagger annotation来声明真正的operationId +Then get `hello` via Getter: + ```java -interface Hello { - String sayHi(String name); - - @ApiOperation(nickname = "sayHi", value = "reactive method for sayHi") - CompletableFuture<String> asyncSayHi(String name); +public Hello getHello() { + return hello; } ``` + +```java +Hello hello = consumer.getHello() +``` + +> NOTE: +> `BeanUtils.getBean` has inner lock so performacen is low , we recommend use once and cache return as local field for future use(such as in constructor). \ No newline at end of file
