有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。https://store.amazingmemo.com/chapterDetail/1685324709017001`
在调用之前、调用之后、出现异常时的事件通知
背景
在调用之前、调用之后、出现异常时,会触发 oninvoke
、onreturn
、onthrow
三个事件,可以配置当事件发生时,通知哪个类的哪个方法。
示例
服务提供者与消费者共享服务接口
1 2 3 4
| interface IDemoService { public Person get(int id); }
|
服务提供者实现
1 2 3 4 5 6
| class NormalDemoService implements IDemoService { public Person get(int id) { return new Person(id, "charles`son", 4); } }
|
服务提供者配置
1 2 3 4 5
| <dubbo:application name="rpc-callback-demo" /> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <bean id="demoService" class="org.apache.dubbo.callback.implicit.NormalDemoService" /> <dubbo:service interface="org.apache.dubbo.callback.implicit.IDemoService" ref="demoService" version="1.0.0" group="cn"/>
|
服务消费者 Callback 接口
1 2 3 4 5
| interface Notify { public void onreturn(Person msg, Integer id); public void onthrow(Throwable ex, Integer id); }
|
服务消费者 Callback 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class NotifyImpl implements Notify { public Map<Integer, Person> ret = new HashMap<Integer, Person>(); public Map<Integer, Throwable> errors = new HashMap<Integer, Throwable>(); public void onreturn(Person msg, Integer id) { System.out.println("onreturn:" + msg); ret.put(id, msg); } public void onthrow(Throwable ex, Integer id) { errors.put(id, ex); } }
|
服务消费者 Callback 配置
1 2 3 4 5
| <bean id ="demoCallback" class = "org.apache.dubbo.callback.implicit.NotifyImpl" /> <dubbo:reference id="demoService" interface="org.apache.dubbo.callback.implicit.IDemoService" version="1.0.0" group="cn" > <dubbo:method name="get" async="true" onreturn = "demoCallback.onreturn" onthrow="demoCallback.onthrow" /> </dubbo:reference>
|
callback
与 async
功能正交分解,async=true
表示结果是否马上返回,onreturn
表示是否需要回调。
两者叠加存在以下几种组合情况:
- 异步回调模式:
async=true onreturn="xxx"
- 同步回调模式:
async=false onreturn="xxx"
- 异步无回调:
async=true
- 同步无回调:
async=false
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| IDemoService demoService = (IDemoService) context.getBean("demoService"); NotifyImpl notify = (NotifyImpl) context.getBean("demoCallback"); int requestId = 2; Person ret = demoService.get(requestId); Assert.assertEquals(null, ret);
for (int i = 0; i < 10; i++) { if (!notify.ret.containsKey(requestId)) { Thread.sleep(200); } else { break; } } Assert.assertEquals(requestId, notify.ret.get(requestId).getId());
|