SpringBoot | Dubbo之Filter使用示例

欢迎参观我的博客,一个Vue 与 SpringBoot结合的产物:https://poetize.cn

  • 博客:https://gitee.com/littledokey/poetize-vue2.git
  • 聊天室:https://gitee.com/littledokey/poetize-im-vue3.git
  • 后端:https://gitee.com/littledokey/poetize.git
  • 七牛云登录/注册地址(文件服务器,CDN):https://s.qiniu.com/Mz6Z32

原文链接:https://poetize.cn/article?id=39

@Activate注解可以设置过滤器的条件和顺序

String[] group():URL中的分组如果匹配则激活
String[] value():URL中如果包含该key值,则会激活
String[] before():填写扩展点列表,表示哪些扩展点要在本扩展点之前激活
String[] after():表示哪些扩展点需要在本扩展点之后激活
int order():排序信息

@Activate(group = Constants.PROVIDER, order = -1):表示在服务提供者有效

@Activate(group = Constants.CONSUMER, value = Constants.ACTIVES_KEY):表示在消费者有效

传递用户信息

@Activate(group = {CommonConstants.CONSUMER})
public class DubboConsumerContextFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        LoginUserVo user = UserContext.getLoginUser();
        if (user != null) {
            RpcContext.getServiceContext().setObjectAttachment(UserConstants.DUBBO_USER_KEY, user);
        }
        return invoker.invoke(invocation);
    }
}

@Activate(group = {CommonConstants.PROVIDER})
public class DubboProviderContextFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Object obj = RpcContext.getServiceContext().getObjectAttachment(UserConstants.DUBBO_USER_KEY);
        if (obj == null) {
            return invoker.invoke(invocation);
        }
        try {
            UserContext.setLoginUser((LoginUserVo) obj);
            return invoker.invoke(invocation);
        } finally {
            UserContext.clear();
        }
    }
}

异常传递

@Activate(group = {CommonConstants.PROVIDER})
@Slf4j
public class ServiceExceptionFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Result result = invoker.invoke(invocation);
        if (result.hasException() && GenericService.class != invoker.getInterface()) {
            try {
                Throwable exception = result.getException();
                if (exception.getCause() != null && exception.getCause() instanceof IOException) {
                    log.error("IOException message: {} ", exception.getCause().getMessage());
                    result.setException(new ServiceIoException((IOException) exception.getCause()));
                } else {
                    //其他异常
                    if (exception.getCause() != null) {
                        log.error("ServiceRpcException message: {} ", exception.getCause().getMessage());
                        result.setException(new ServiceRpcException((Exception) exception.getCause()));
                    }
                }
            } catch (Throwable e) {
                log.warn("Fail to ServiceExceptionFilter when called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
            }
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用SpringBoot + Dubbo框架的项目集成Seata,需要进行以下步骤: 1. 添加Seata的相关依赖 在项目的pom.xml文件添加Seata的相关依赖: ```xml <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>${seata.version}</version> </dependency> ``` 2. 配置Seata的注册心 在项目的application.properties或application.yml文件添加Seata的注册心配置,例如: ```yaml spring: cloud: alibaba: seata: tx-service-group: my_test_tx_group config: type: nacos nacos: server-addr: localhost:8848 namespace: seata registry: type: nacos nacos: server-addr: localhost:8848 application: seata-server ``` 其,tx-service-group是Seata的事务组名称,config和registry是Seata的注册心配置,这里使用的是Nacos作为注册心,也可以使用其他的注册心。 3. 配置Dubbo的Seata拦截器 在Dubbo的服务提供方和服务消费方都需要添加Seata的拦截器,以实现分布式事务的管理。在SpringBoot + Dubbo框架,可以通过配置文件或注解的方式来添加Seata的拦截器。 (1)配置文件方式 在Dubbo的服务提供方和服务消费方的application.properties或application.yml文件添加Seata的拦截器配置,例如: ```yaml # 服务提供方 dubbo.provider.filter=seata # 服务消费方 dubbo.consumer.filter=seata ``` (2)注解方式 在Dubbo的服务提供方和服务消费方的实现使用@DubboService和@DubboReference注解来定义Dubbo服务,同时在@DubboService和@DubboReference注解添加filter属性来指定Seata的拦截器,例如: ```java // 服务提供方 @DubboService(version = "1.0.0", filter = {"seata"}) public class OrderServiceImpl implements OrderService { // ... } // 服务消费方 public class UserServiceImpl implements UserService { @DubboReference(version = "1.0.0", filter = {"seata"}) private OrderService orderService; // ... } ``` 4. 编写分布式事务代码 在Dubbo的服务提供方和服务消费方,通过Seata提供的API来实现分布式事务的管理,例如: ```java // 服务提供方 @Service public class OrderServiceImpl implements OrderService { @Override @GlobalTransactional public void createOrder(Order order) { // 保存订单信息 orderMapper.insert(order); // 扣减库存 storageService.reduceStock(order.getProductId(), order.getCount()); // 扣减余额 accountService.reduceBalance(order.getUserId(), order.getMoney()); } } // 服务消费方 @Service public class UserServiceImpl implements UserService { @DubboReference(version = "1.0.0") private OrderService orderService; @Override @GlobalTransactional public void createUser(User user, Order order) { // 注册用户 userMapper.insert(user); // 创建订单 orderService.createOrder(order); } } ``` 在以上代码使用@GlobalTransactional注解来标记分布式事务的范围,Seata会根据这个注解来创建全局事务,并在所有涉及到的服务进行事务的协调和管理。 综上所述,以上就是在SpringBoot + Dubbo框架使用Seata进行分布式事务管理的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值