dubbo学习笔记四(异步调用)
相关资料
项目结构
代码示例
- [EchoTestApp]
@RestController
@SpringBootApplication
@ImportResource("classpath:/consumer.xml")
public class EchoTestApp {
@Autowired
private ClientService clientService;
@GetMapping("/hi/{name}")
public String hello(@PathVariable(name = "name") String name) throws InterruptedException, ExecutionException, TimeoutException {
return clientService.echo(name);
}
public static void main(String[] args) {
System.getProperties().put("server.port", 7070);
SpringApplication.run(EchoTestApp.class, args);
}
@Configuration
@EnableDubbo(scanBasePackages = "consumer")
@PropertySource("classpath:/dubbo-consumer.properties")
static public class ConsumerConfiguration {
}
}
和之前的区别在于 @ImportResource("classpath:/consumer.xml") 引入dubbo的xml配置
至于为什么用xml呢?因为没有找到 dubbo 事件通知 api 的参考示例
- [consumer.xml]
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="annotation-consumer"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:reference id="echoService" check="false" interface="com.xh.dubbo.learn.lesson2.api.IEchoService">
<dubbo:method name="echo" async="true" onreturn="notify.onReturn" onthrow="notify.onThrow"/>
</dubbo:reference>
<bean class="com.xh.dubbo.learn.lesson2.service.ClientService" id="clientService">
<property name="echoService" ref="echoService"></property>
</bean>
</beans>
-
[dubbo-consumer.properties] 注释掉里面的所有配置,应为不能和上面的重复
-
[ClientService] 注释掉里面的重复配置
package com.xh.dubbo.learn.lesson2.service;
import com.xh.dubbo.learn.lesson2.api.IEchoService;
import org.apache.dubbo.rpc.RpcContext;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/*@Service*/
public class ClientService {
/**
* xml和注解不能同时定义
*/
/* @Reference*/
private IEchoService echoService;
public String echo(String msg) throws ExecutionException, InterruptedException, TimeoutException {
String result = echoService.echo(msg);// 这里的返回值为空,请不要使用
Future<String> future = RpcContext.getContext().getFuture();
// 业务线程可以开始做其他事情
System.out.println("start do other thing...");
//Thread.sleep(100);
System.out.println("print result:" + result);
System.out.println("other thing is done");
result = future.get(3000, TimeUnit.MILLISECONDS); // 阻塞需要获取异步结果时,也可以使用 get(timeout, unit) 设置超时时间
return result == null ? "error result" : result;
}
public IEchoService getEchoService() {
return echoService;
}
public void setEchoService(IEchoService echoService) {
this.echoService = echoService;
}
}
- [INotify]
public interface INotify {
void onReturn(String returnStr, String arg);
void onThrow(Throwable ex, String arg);
}
- [NotifyImpl]
@Component("notify")
public class NotifyImpl implements INotify {
public void onReturn(String returnStr, String arg) {
System.out.println("do something onReturn");
System.out.println(returnStr);
System.out.println(arg);
}
public void onThrow(Throwable ex, String arg) {
System.out.println("do something onThrow");
System.out.println(ex.getMessage());
System.out.println(arg);
}
}
需要注意的是以上方法的参数的类型和个数需要和配置文件中的比如 notify.onReturn 一致,只是前面多了返回值或者异常
输出
控制台
start do other thing...
print result:null
other thing is done
do something onReturn
echo: 哈哈哈
哈哈哈