比如当前有个需求,需要拦截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中拦截生产者或消费者服务方法调用的更多相关文章

  1. dubbo源码分析2-reference bean发起服务方法调用

    dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...

  2. Java中的生产者、消费者问题

    Java中的生产者.消费者问题描述: 生产者-消费者(producer-consumer)问题, 也称作有界缓冲区(bounded-buffer)问题, 两个进程共享一个公共的固定大小的缓冲区(仓库) ...

  3. java多线程中的生产者与消费者之等待唤醒机制@Version1.0

    一.生产者消费者模式的学生类成员变量生产与消费demo,第一版1.等待唤醒:    Object类中提供了三个方法:    wait():等待    notify():唤醒单个线程    notify ...

  4. Java中的生产者和消费者实例(多线程 等待唤醒机制)

    1.什么是等待唤醒 我们实现的效果 创建生产者和消费者  对服装进行生产  和售卖 实现生产一个就消费一个 来观察线程的各种状态 下面是用到的方法: wait()方法:让一个线程进行等待 另外一个线程 ...

  5. Linux内核中实现生产者与消费者(避免无效唤醒)【转】

    转自:http://blog.csdn.net/crazycoder8848/article/details/42581399 本文关注的重点是,避免内核线程的无效唤醒,并且主要是关注消费者线程的设计 ...

  6. dubbo+zookeeper下生产者和消费者配置(基于springboot开发)

    一.总共分为三个目录: dubbo-api      服务的接口用于对接客户端和服务端 dubbo-client     客户端配置文件为:consumer.xml dubbo-service  服务 ...

  7. Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

    在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...

  8. Android中使用ContentProvider进行跨进程方法调用

    原文同一时候发表在我的博客 点我进入还能看到很多其它 需求背景 近期接到这样一个需求,须要和别的 App 进行联动交互,比方下载器 App 和桌面 App 进行联动.桌面的 App 能直接显示下载器 ...

  9. java多线程中的生产者与消费者之等待唤醒机制@Version2.0

    二.生产者消费者模式的学生类成员变量生产与消费demo, @Version2.0 在学生类中添加同步方法:synchronized get()消费者,synchronized set()生产者 最终版 ...

随机推荐

  1. pyqt5-复合控件中的子控件

    天子骄龙

  2. python接口自动化一(发送get请求)

    一.环境安装 1.用pip安装requests模块 >>pip install requests 二.get请求 1.导入requests后,用get方法就能直接访问url地址,如:htt ...

  3. 解决 Failed to start LSB: Bring up/down networking 问题

    我用的是虚拟机,一换网络环境虚拟机的ip就没有了,重启网上就报Failed to start LSB: Bring up/down networking错误.网上查了一圈说什么HWADDR有问题,改了 ...

  4. 【leetcode】1210. Minimum Moves to Reach Target with Rotations

    题目如下: In an n*n grid, there is a snake that spans 2 cells and starts moving from the top left corner ...

  5. 启动 jvm 参数小总结

    1.启动某项目 nohup java -jar -Xms256m -Xmx512m -Dspring.config.location=/config/application.yml -Dfile.en ...

  6. 【webpack4】webpack4配置需要注意的问题

    需要注意的知识: 要全局安装webpack以及webpack cli,否则不能使用webpack指令 npm install webpack -g npm install webpack-cli -g ...

  7. PHP基础教程 10款人气暴涨的PHP开源工具

    若想创建动态而又新颖的Web应用程序,PHP便是理想的选择.不用说,在Web开发世界里,PHP是最流行的语言之一.一些非常好用的PHP开源工具着实拯救了不少开发任务繁重的PHP开发 人员,减轻他们的开 ...

  8. Python抽象类(abc模块)

    1.抽象类概念 抽象类是一个特殊的类,只能被继承,不能实例化 2.为什么要有抽象类 其实在未接触抽象类概念时,我们可以构造香蕉.苹果.梨之类的类,然后让它们继承水果这个基类,水果的基类包含一个eat函 ...

  9. Javascript高级程序设计第三版-笔记

    1.JS数值最大值最小值: >Number.MIN_VALUE <5e-324 >Number.MAX_VALUE <1.7976931348623157e+308 判断数值是 ...

  10. Vue项目开发,nprogress进度条加载之超详细讲解及实战案例

    Nprogress的默认进度条很细,它的设计灵感主要来源于 谷歌,YouTube 他的安装方式也很简单,你可以有两种使用方式: 直接引入js和css文件 使用npm安装的的方式 直接引入: Npm安装 ...