dubbo中拦截生产者或消费者服务方法调用
比如当前有个需求,需要拦截dubbo的服务提供方或者服务消费方的方法,判断参数中是否包含某个关键字进行拦截阻止执行,那么我们可以通过使用dubbo的SPI机制通过实现Filter类来拦截,话不多说直接上代码:
1、新建一个类实现dubbo的Filter接口
/**
* 回滚任务Dubbo拦截正在回滚或备份小区的方法调用,阻止执行
* @author wl
* @date 2019-08-16 13:24
*/
@Activate(group={ Constants.PROVIDER, Constants.CONSUMER })
public class DubboRollbackTaskFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(DubboRollbackTaskFilter.class); private RedisTemplate redisTemplate; /**
* Filter中@Autowired会失效
* 使用dubbo自动注入redisTemplate类
* @param redisTemplate
*/
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
} public static final String ROLLBACK_READIS_KEY = "server_rollback_task_region_ids"; @Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
try {
String method = invocation.getMethodName();
String name = invoker.getInterface().getName();
Object[] args = invocation.getArguments();
String ageString = JSON.toJSONString(args);
// redis中获取数据
Object redisValues = redisTemplate.opsForValue().get(DubboRollbackTaskFilter.ROLLBACK_READIS_KEY);
logger.debug(">>>>>dubboRollbackTaskFilter-className:{},method:{},args:{},redisValues:{}", name, method, ageString, JSON.toJSONString(redisValues));
if (null != redisValues && redisValues.toString().trim().length() > 0) {
String[] regionIds = redisValues.toString().split(",");
for (String regionId : regionIds) {
if (regionId.trim().length() <= 0) {
continue;
}
// 只要包含当前有处理的小区,那么直接抛出参数异常
if (ageString.contains(regionId)) {
logger.info(">>>>>dubboRollbackTaskFilter-拦截:{},method:{},args:{},regionId:{}", name, method, ageString, regionId);
return new RpcResult(new IllegalArgumentException("回滚任务拦截提示:当前小区正在备份或回滚数据,一切操作不允许执行!"));
}
}
}
} catch (Exception e) {
// 拦截异常,不影响正常操作
logger.error(">>>>>dubboRollbackTaskFilter-异常", e);
}
return invoker.invoke(invocation);
}
}
2、META-INF下新建文件

文件内容为:
dubboRollbackTaskFilter=com.qdingnet.pcloud.helper.utils.DubboRollbackTaskFilter
至此就可以成功的拦截你想拦截的东西
3、下面解释几个点:
1、关于@Activate,Activate注解表示一个扩展是否被激活,可以放在类定义和方法上,dubbo用它在spi扩展类定义上,表示这个扩展实现被激活。
具体如何实现可以百度或看下(这篇文章)
如果不使用此注解可以直接在配置中添加
1.1 比如配置中添加 dubbo.provider.filter =dubboServiceFilter
1.2 或者在dubbo配置xml中添加 <dubbo:provider filter="xxxFilter" /> 或者 <dubbo:consumer filter="xxxFilter" /> 使Filter生效
2、关于在Filter中使用@Resoure或@Autowired
在dubbo拦截器中以上两个注解是不会生效的,我们可以用以下两种方式注入
2.1 可以采取通过setter方式来注入其他的bean,就像最上面的代码示例
2.2 通过Spring的ApplicationContextAware接口

2.3 直接从Spring中取,ServiceBean.getSpringContext().getBean(clazz)
3、说说拦截的invoke返回方式
如果想直接返回自定义的拦截,直接使用dubbo提供的RpcResult,然后将异常作为参数传给此类进行返回
dubbo中拦截生产者或消费者服务方法调用的更多相关文章
- dubbo源码分析2-reference bean发起服务方法调用
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- Java中的生产者、消费者问题
Java中的生产者.消费者问题描述: 生产者-消费者(producer-consumer)问题, 也称作有界缓冲区(bounded-buffer)问题, 两个进程共享一个公共的固定大小的缓冲区(仓库) ...
- java多线程中的生产者与消费者之等待唤醒机制@Version1.0
一.生产者消费者模式的学生类成员变量生产与消费demo,第一版1.等待唤醒: Object类中提供了三个方法: wait():等待 notify():唤醒单个线程 notify ...
- Java中的生产者和消费者实例(多线程 等待唤醒机制)
1.什么是等待唤醒 我们实现的效果 创建生产者和消费者 对服装进行生产 和售卖 实现生产一个就消费一个 来观察线程的各种状态 下面是用到的方法: wait()方法:让一个线程进行等待 另外一个线程 ...
- Linux内核中实现生产者与消费者(避免无效唤醒)【转】
转自:http://blog.csdn.net/crazycoder8848/article/details/42581399 本文关注的重点是,避免内核线程的无效唤醒,并且主要是关注消费者线程的设计 ...
- dubbo+zookeeper下生产者和消费者配置(基于springboot开发)
一.总共分为三个目录: dubbo-api 服务的接口用于对接客户端和服务端 dubbo-client 客户端配置文件为:consumer.xml dubbo-service 服务 ...
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...
- Android中使用ContentProvider进行跨进程方法调用
原文同一时候发表在我的博客 点我进入还能看到很多其它 需求背景 近期接到这样一个需求,须要和别的 App 进行联动交互,比方下载器 App 和桌面 App 进行联动.桌面的 App 能直接显示下载器 ...
- java多线程中的生产者与消费者之等待唤醒机制@Version2.0
二.生产者消费者模式的学生类成员变量生产与消费demo, @Version2.0 在学生类中添加同步方法:synchronized get()消费者,synchronized set()生产者 最终版 ...
随机推荐
- 在Windows 10 操作系统打开Windows Mobile 设备中心,要么双击无反应,要么正在启动后过会就关闭了
在Windows 10 操作系统打开Windows Mobile 设备中心,要么双击无反应,要么正在启动后过会就关闭了 解决方法: 1.运行:输入services.msc进入服务 2.找到(前提你的P ...
- C#对应JavaScript的银行家舍入规则(Math.Round()对应toFixed(f))
Math.Round((n * u - t * u )/ u, f);//这里使用银行家四舍五入对应JS的 toFixed() ((n * u - t * u) / u).toFixed(f) f为小 ...
- 通过页面名字调用页面并添加到tab控件中
/// <summary> /// 动态 显示 tab /// </summary> /// <param name="sFromName">类 ...
- 如何查看 mysql 的视图?
1.查询表(包括view) mysql> use iips; Database changed mysql> show tables; +------------------------- ...
- Python爬虫十六式 - 第四式: 使用Xpath提取网页内容
Xpath:简单易用的网页内容提取工具 学习一时爽,一直学习一直爽 ! Hello,大家好,我是Connor,一个从无到有的技术小白.上一次我们说到了 requests 的使用方法.到上节课为止, ...
- go语言系列--输出正弦函数
实验所用到的标准库和包 库与包之间的理解可以类比成:数据库种的库和表 库名 作用 image 常见图形格式的访问及生成 log 日志记录库 math 数学库 os 操作系统平台不依赖平台操作封装 查看 ...
- springboot(六) Maven打包引入本地jar包
springboot Maven打包引入本地jar包 最近在做项目的时候,有一些jar包不存在maven的依赖库中,所以需要自己引入本地jar包来达到需求,那么我们该如何去将本地的jar包引入s ...
- linux 文本文件显示行数
一般的我们在使用linux编辑器编辑文本文件的时候是不会像其他编程软件一样显示行数 临时方法: 在命令模式下输入:set nu或者:set number都可以为vi设置行号,如果要取消的话,则输入:s ...
- vue 在移动端实现红包雨 (兼容性好)
下面是代码:<template> <div class="ser_home"> <ul class="red_packe ...
- DjangoRestFrameWork 版本控制
DRF的版本控制 为什么需要版本控制 API 版本控制允许我们在不同的客户端之间更改行为(同一个接口的不同版本会返回不同的数据). DRF提供了许多不同的版本控制方案. 可能会有一些客户端因为某些原因 ...