图片来源:点击打开链接
整个异步过程图片描述的很清楚,下面来看看代码:
一、服务提供者
1、服务提供者接口
package com.test.dubboser;
public interface ServiceDemo2 {
public Person getPerson(String str,int age);
}
package com.test.dubboser;
import java.io.Serializable;
public class Person implements Serializable {
/**
*
*/
private static final long serialVersionUID = 8661104133888956335L;
private int age;
private String name;
public Person(){}
public Person(int age ,String name){
this.age= age;
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
StringBuffer buffer= new StringBuffer();
buffer.append("name:"+name+"\t");
buffer.append("age:"+age);
return buffer.toString();
}
}
3、服务提供者接口实现类
package com.test.dubboser;
public class ServiceImp2 implements ServiceDemo2{
public Person getPerson(String str,int age) {
Person person=new Person();
person.setName(str);
person.setAge(age);
return person;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 提供方应用信息,用于计算依赖关系,这个和client没必要一致 -->
<dubbo:application name="hello-world-app-my" />
<!-- 多注册中心配置 -->
<dubbo:registry protocol="zookeeper" address="192.168.0.102:2181"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.test.dubboser.ServiceDemo"
ref="demoService"/>
<dubbo:service interface="com.test.dubboser.ServiceDemo2"
ref="demoService2"/>
<dubbo:service interface="com.test.dubboser.CacheService"
ref="cacheService"/>
<!--和本地bean一样实现服务 -->
<bean id="demoService" class="com.test.dubboser.ServiceImp"/>
<bean id="demoService2" class="com.test.dubboser.ServiceImp2"/>
<!-- 结果缓存 -->
<bean id="cacheService" class="com.test.dubboser.CacheServiceImp"/>
</beans>
二、服务消费者
1、配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer-of-helloworld-app-my" />
<!-- 使用zookeeper广播注册中心暴露发现服务地址 -->
<dubbo:registry protocol="zookeeper" address="192.168.0.102:2181"/>
<!--获取服务 -->
<dubbo:reference id="demoServicemy" interface="com.test.dubboser.ServiceDemo"/>
<!--异步功能实现-->
<dubbo:reference id="demoServicemy2" interface="com.test.dubboser.ServiceDemo2">
<dubbo:method name="getPerson" async="true" />
</dubbo:reference>
<!--结果缓存配置 -->
<dubbo:reference id="cacheService" interface="com.test.dubboser.CacheService" cache="true"/>
</beans>
注意这里的这一行,实现异步配置
<dubbo:reference id="demoServicemy2" interface="com.test.dubboser.ServiceDemo2">
<dubbo:method name="getPerson" async="true" />
</dubbo:reference>
2、消费者代码
package com.test.dubbocli;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.alibaba.dubbo.rpc.RpcContext;
import com.test.dubboser.CacheService;
import com.test.dubboser.Person;
import com.test.dubboser.ServiceDemo;
import com.test.dubboser.ServiceDemo2;
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
run();
}
public static void run() throws InterruptedException, ExecutionException{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationConsumer.xml" });
context.start();
//ServiceDemo demoServer = (ServiceDemo) context.getBean("demoServicemy");
ServiceDemo2 demoServer2 = (ServiceDemo2) context.getBean("demoServicemy2");
/*ServiceDemo demoServer3 = (ServiceDemo) context.getBean("demoServicemy3");*/
/*String str=demoServer.say("java ---->>>");*/
//调用后立即返回null
Person person=demoServer2.getPerson("www", 13);
System.err.println("立即返回的为null:"+person);
//拿到调用的Future引用,当结果返回后,会被通知和设置到此Future。
Future<Person> pFuture = RpcContext.getContext().getFuture();
//如果Person已返回,直接拿到返回值,否则线程wait,等待Person返回后,线程会被notify唤醒。
person = pFuture.get();
System.out.println("返回的有值"+person);
System.out.println(person);
}
}
3、运行结果
立即返回的为null:null
future中获取值:name:www age:13
三、异步返回值,和异步无返回值
你也可以设置是否等待消息发出:(异步总是不等待返回)
1、sent="true" 等待消息发出,消息发送失败将抛出异常。
2、sent="false" 不等待消息发出,将消息放入IO队列,即刻返回。
<dubbo:reference id="demoServicemy2" interface="com.test.dubboser.ServiceDemo2">
<dubbo:method name="getPerson" async="true" sent="true" />
</dubbo:reference>
3、
如果你只是想异步,完全忽略返回值,可以配置return="false",以减少Future对象的创建和管理成本:
<dubbo:reference id="demoServicemy2" interface="com.test.dubboser.ServiceDemo2">
<dubbo:method name="getPerson" async="true" return="false" />
</dubbo:reference>
设置了return =“false”后我们就获取不到Future对象,当然就获取不到返回值,这样就只有异步调用了服务端方法而没有返回值,执行的流程也就是最开始图形中的1和2 这两步,没有了其他的步骤所以速度也就比较快……