号外号外:麻烦点击左侧
我正在参加博客之星评选,请您投票
,给个五星好评,谢谢大家了!!!
1:写在前面
事件通知,用于在调用服务提供者的过程中,配置调用过程中的监听,如配置当开始调用时调用消费者端某方法,执行完毕正常返回时调用消费者端某方法,执行的过程中发生了异常调用消费者端某方法,其实就是一种监听机制,当特定的事件发生时,执行特定的逻辑,下面我们一起来看下。
2:服务提供者端
2.1:服务接口
public interface MyEventNotifyService {
/**
* 获取用户名字
*
* @param userId
* @return
*/
String getUserName(String userId);
}
2.2:服务接口实现
public class MyEventNotifyServiceImpl implements MyEventNotifyService {
private static final String USER_ID = "1503892";
@Override
public String getUserName(String userId) {
if (StringUtils.isBlank(userId)) {
throw new RpcException("userId is null");
}
return USER_ID.equals(userId) ? "董事爸爸" : "";
}
}
2.3:xml
<?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="dongshidaddy-provider" owner="dongshidaddy"/>
<dubbo:registry address="zookeeper://192.168.10.119:2181" />
<!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->
<!-- <dubbo:protocol name="dubbo" port="20827"/>-->
<dubbo:protocol name="dubbo" port="20827"/>
<dubbo:service interface="dongshi.daddy.service.MyEventNotifyService" ref="myEventNotifyService"/>
<!--Bean bean定义-->
<bean id="myEventNotifyService" class="dongshi.daddy.service.MyEventNotifyServiceImpl"/>
</beans>
2.4:main
public class MyProviderWithEventNotifyMain {
public static void main(String[] args) throws Exception {
//加载xml配置文件启动
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext("META-INF/spring/provider-with-event-notify.xml");
context.start();
System.in.read(); // 按任意键退出
}
}
启动后,在zk中查看手动解码后的
:
[zk: localhost:2181(CONNECTED) 2] ls /dubbo/dongshi.daddy.service.MyEventNotifyService/providers
[dubbo://192.168.10.119:20827/dongshi.daddy.service.MyEventNotifyService?anyhost=true&application=dongshidaddy-provider&bean.name=dongshi.daddy.service.MyEventNotifyService&dubbo=2.0.2&generic=false&interface=dongshi.daddy.service.MyEventNotifyService&methods=getUserName&owner=dongshidaddy&pid=14532&side=provider×tamp=1638445588833]
3:服务消费者
3.1:xml
<?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="dongshidaddy-consumer" owner="dongshidaddy"/>
<!--点对点的方式-->
<dubbo:registry address="zookeeper://192.168.10.119:2181" />
<dubbo:reference id="myEventNotifyServiceInConsumerSide"
interface="dongshi.daddy.service.MyEventNotifyService"/>
<bean class="dongshi.daddy.service.eventynotify.ConsumerNotifyServiceImpl" id="consumerNotifyServiceImpl"/>
</beans>
3.2:main
public class ConsumerWithEventNotifyMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext("consumer-with-event-notify.xml");
context.start();
MyEventNotifyService myEventNotifyService
= (dongshi.daddy.service.MyEventNotifyService) context.getBean("myEventNotifyServiceInConsumerSide");
// 正常调用
System.out.println("---" + myEventNotifyService.getUserName("1503892") + "---");
// 发生异常
System.out.println("---" + myEventNotifyService.getUserName("") + "---");
}
}
输出如下:
---董事爸爸---
...
Exception in thread "main" com.alibaba.dubbo.rpc.RpcException: userId is null
at dongshi.daddy.service.MyEventNotifyServiceImpl.getUserName(MyEventNotifyServiceImpl.java:12)
可以看到正常返回和发生异常的信息,下面我们通过事件通知来配置在正常返回和发生异常时执行一个指定的方法。
3.3:事件通知接口和实现类
作为java,首先肯定是要有规范的,即要定义接口。
/**
* @author wx
* @date 2020/9/8 1:53 下午
*/
public interface ConsumerNotifyService {
/**
* 调用之前
* @param name 参数和dongshi.daddy.service.MyEventNotifyService#getUserName(java.lang.String)保持一致
*/
void onInvoke(String name);
/**
* 无参数:调用之后
* @param result 参数用于接收 [事件通知]服务接口的方法返回值类型保持一致
*/
// void onReturnWithoutParam(String result);
/**
* 有参数:调用之后,方法格式(返回值,服务接口方法参数列表)
* @param result 第一个参数 接收 [事件通知]服务接口的方法返回值类型保持一致
* @param name 第二个或者之后,与[事件通知]服务接口的方法入参保持一致
*/
void onReturn(String result, String name);
/**
* 抛异常 方法格式(服务提供者抛出的异常信息,服务接口方法入参)
* @param ex
* @param name
*/
void onThrow(Throwable ex, String name);
}
public class ConsumerNotifyServiceImpl implements ConsumerNotifyService{
@Override
public void onInvoke(String name) {
System.out.println("[事件通知]执行onInvoke方法,参数:" + name);
}
/*
@Override
public void onReturnWithoutParam(String result) {
System.out.println("[事件通知]执行onReturnWithoutParam方法,返回结果:" + result);
}
*/
@Override
public void onReturn(String result, String name) {
System.out.println("[事件通知]执行onReturn方法,参数:" + name + ", 返回结果:" + result);
}
@Override
public void onThrow(Throwable ex, String name) {
System.out.println("[事件通知]执行onThrow方法,参数:" + name + ", 异常信息:" + ex.getMessage());
}
}
3.4:修改xml
通过在dubbo:method 中配置如下标签完成事件通知的配置:
修改后xml如下:
<?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="dongshidaddy-consumer" owner="dongshidaddy"/>
<!--点对点的方式-->
<dubbo:registry address="zookeeper://192.168.10.119:2181" />
<dubbo:reference id="myEventNotifyServiceInConsumerSide"
interface="dongshi.daddy.service.MyEventNotifyService">
<dubbo:method name="getUserName"
onreturn="consumerNotifyServiceImpl.onReturn"
oninvoke="consumerNotifyServiceImpl.onInvoke"
onthrow="consumerNotifyServiceImpl.onThrow"/>
</dubbo:reference>
<bean class="dongshi.daddy.service.eventynotify.ConsumerNotifyServiceImpl" id="consumerNotifyServiceImpl"/>
</beans>
含义如下:
oninvoke:调用时执行spring bean consumerNotifyServiceImpl#onInvoke。
onreturn:调用正常返回后执行spring bean consumerNotifyServiceImpl#onReturn。
onthrow:调用过程发生异常执行spring bean consumerNotifyServiceImpl#onThrow。
再次执行main函数,输出如下:
[事件通知]执行onInvoke方法,参数:1503892
[事件通知]执行onReturn方法,参数:1503892, 返回结果:董事爸爸
---董事爸爸---
[事件通知]执行onInvoke方法,参数:
[事件通知]执行onThrow方法,参数:, 异常信息:userId is null
...MyEventNotifyService&methods=getUserName&owner=dongshidaddy&pid=12396&side=consumer×tamp=1638509220771, dubbo version: 2.6.6, current host: 192.168.10.119
Exception in thread "main" com.alibaba.dubbo.rpc.RpcException: userId is null
可以看到事件通知可以正常执行了。