码迷,mamicode.com
首页 > 其他好文 > 详细

dubbo中拦截生产者或消费者服务方法调用

时间:2019-08-19 17:28:37      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:oca   classname   read   使用   添加   ext   参数   生产者   lan   

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

标签:oca   classname   read   使用   添加   ext   参数   生产者   lan   

原文地址:https://www.cnblogs.com/wanglu/p/11378164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!