SpringIntegration消息路由之Router的条件路由与过滤功能

2025-04-02 03:50

本文主要是介绍SpringIntegration消息路由之Router的条件路由与过滤功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringIntegration消息路由之Router的条件路由与过滤功能》本文详细介绍了Router的基础概念、条件路由实现、基于消息头的路由、动态路由与路由表、消息过滤与选择性路由以及错误处理...

引言

在企业集成架构中,消息路由是一个至关重要的环节,它负责根据预定的规则将消息分发到不同的目标通道。Spring Integration作为企业集成模式的实现框架,提供了强大的Router组件来满足各种复杂的路由需求。Router可以根据消息的内容、消息头或其它条件,智能地决定消息的流向,从而使系统的各个组件能够专注于自己的核心功能,提高了系统的模块化程度和可维护性。本文将深入探讨Spring Integration中Router的实现方式和应用场景,特别是条件路由和消息过滤的相关技术,通过具体示例展示如何在实际项目中有效地使用这些功能。

一、Router基础概念

Router是Spring Integration中的核心组件之一,其主要职责是根据特定的条件将输入消息路由到一个或多个输出通道。通过Router,可以构建灵活的消息流,实现业务逻辑的动态分支处理。Spring Integration提供了多种类型的Router实现,包括PayloadTypeRouter、HeaderValueRouter、RecipientListRouter、ExpressionEvaLuatingRouter等,开发人员可以根据具体需求选择合适的Router类型。Router的工作原理是接收来自输入通道的消息,根据配置的路由规则评估消息,然后决定将消息发送到哪个或哪些输出通道。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@Configuration
public class BasicRouterConfig {
    // 定义通道
    @Bean
    public MessageChannel inputChannel() {
        return new DirectChannel();
    }
    @Bean
    public MessageChannel orderChannel() {
        return new DirectChannel();
    }
    @Bean
    public MessageChannel inventoryChannel() {
        return new DirectChannel();
    }
    @Bean
    public MessageChannel customerChannel() {
        return new DirectChannel();
    }
    // 基础路由器实现
    @Bean
    @Router(inputChannel = "inputChannel")
    public String route(Message<?> message) {
        // 根据消息的不同类型路由到不同的通道
        Object payload = message.javascriptgetPayload();
        if (payload instanceof Order) {
            return "orderChannel";
        } else if (payload instanceof InventoryItem) {
            return "inventoryChannel";
        } else if (payload instanceof Customer) {
            return "customerChannel";
        } else {
            throw new IllegalArgumentException("未知消息类型: " + payload.getClass().getName());
        }
    }
    // 示例数据类
    public static class Order {
        private String orderId;
        // 其他字段省略
    }
    public static class InventoryItem {
        private String itemId;
        // 其他字段省略
    }
    public static class Customer {
        private String customerId;
        // 其他字段省略
    }
}

二、条件路由实现

条件路由是指根据消息内容或消息头信息中的特定条件,将消息路由到不同的目标通道。Spring Integration提供了多种方式来实现条件路由,包括使用SpEL表达式、Java DSL和基于注解的配置。ExpressionEvaluatingRouter允许使用SpEL表达式定义路由条件,使得复杂的路由逻辑可以通过简洁的表达式实现。通过条件路由,系统可以根据业务规则动态地决定消息的处理流程,例如根据订单金额将订单分为高优先级和普通优先级处理,或者根据客户类型提供不同级别的服务。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.router.ExpressionEvaluatingRouter;
import org.springframework.messaging.MessageChannel;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ConditionalRouterConfig {
    // 使用SpEL表达式的条件路由器
    @Bean
    @Router(inputChannel = "orderInputChannel")
    public ExpressionEvaluatingRouter orderRouter() {
        ExpressionEvaluatingRouter router = new ExpressionEvaluatingRouter("payload.amount > 1000 ? 'vipOrderChannel' : 'regularOrderChannel'");
        router.setChannelMapping("true", "vipOrderChannel");
        router.setChannelMapping("false", "regularOrderChannel");
        return router;
    }
    // 使用Java DSL的方式配置条件路由
    @Bean
    public org.springframework.integration.dsl.IntegrationFlow conditionRoutingFlow() {
        return org.springframework.integration.dsl.IntegrationFlows
                .from("paymentInputChannel")
                .<Payment, String>route(
                        payment -> {
                            if (payment.getAmount() < 100) {
                                return "smallPaymentChannel";
                            } else if (payment.getAmount() < 1000) {
                                return "mediumPaymentChannel";
                            } else {
                                return "largePaymentChannel";
                            }
                        },
                        mapping -> mapping
                                .subFlowMapping("smallPaymentChannel", sf -> sf
                                        .handle(message -> {
                                            System.out.println("处理小额支付: " + message.getPayload());
                                        }))
                                .subFlowMapping("mediumPaymentChannel", sf -> sf
                                        .handle(message -> {
                                            System.out.println("处理中额支付: " + message.getPayload());
                                        }))
                                .subFlowMapping("largePaymentChannel", sf -> sf
                                        .handle(message -> {
                                            System.out.println("处理大额支付: " + message.getPayload());
                                        }))
                )
                .get();
    }
    // 多条件路由示例
    @Bean
    @Router(inputChannel = "customerInputChannel")
    public String routeCustomer(Customer customer) {
        // 根据客户类型和信用评分路由
        if (customer.getType().equals("VIP") && customer.getCreditScore() > 700) {
            return "premiumServiceChannel";
        } else if (customer.getType().equals("VIP")) {
            return "vipServiceChannel";
        } else if (customer.getCreditScore() > 700) {
            return "priorityServiceChannel";
        } else {
            return "regularServiceChannel";
        }
    }
    // 示例数据类
    public static class Payment {
        private double amount;
        public double getAmount() {
            return amount;
        }
    }
    public static class Customer {
        private String type;
        private int creditScore;
        public String getType() {
            return type;
        }
        public int getCreditScore() {
            return creditScore;
        }
    }
}

三、基于消息头的路由

在企业集成场景中,消息头通常包含了重要的元数据,如消息类型、优先级、来源系统等信息,这些信息对于路由决策十分有用。HeaderValueRouter专门用于根据消息头的值进行路由,简化了基于消息头的路由配置。通过消息头路由,可以在不解析消息内容的情况下快速做出路由决策,提高了系统性能,同时也使得路由逻辑与业务逻辑分离,增强了系统的模块化程度。这种路由方式特别适合于处理来自不同系统的消息,或者需要根据消息的元数据进行分类处理的场景。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.router.HeaderValueRouter;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
@Configuration
public class HeaderBasedRouterConfig {
    // 基于消息头的路由器
    @Bean
    @Router(inputChannel = "requestChannel")
    public HeaderValueRouter messageTypeRouter() {
        HeaderValueRouter router = new HeaderValueRouter("message-type");
        router.setChannelMapping("ORDER", "orderProcessingChannel");
        router.setChannelMapping("INVENTORY", "inventoryManagementChannel");
        router.setChannelMapping("SHIPPING", "shippingChannel");
        router.setChannelMapping("PAYMENT", "paymentProcessingChannel");
        // 设置默认通道,当没有匹配的消息头值时使用
        router.setDefaultOutputChannelName("unknownMessageChannel");
        return router;
    }
    // 消息头注入示例
    @Bean
    public org.springframework.integration.transformer.HeaderEnricher headerEnricher() {
        Map<String, Object> headersToAdd = new HashMap<>();
        headersToAdd.put("message-type", "ORDER");
        headersToAdd.put("priority", "HIGH");
        return new org.springframework.integration.transformer.HeaderEnricher(headersToAdd);
    }
    // 发送消息的示例方法
    public void sendMessage() {
        // 创建包含消息头的消息
        Message<String> orderMessage = MessageBuilder
                .withPayload("订单数据内容")
                .setHeader("message-type", "ORDER")
                .setHeader("priority", "HIGH")
                .build();
        Message<String> inventoryMessage = MessageBuilder
                .withPayload("库存数据内容")
                .setHeader("message-type", "INVENTORY")
                .setHeader("priority", "MEDIUM")
                .build();
        // 将消息发送到requestChannel,路由器会根据message-type头进行路由
        requestChannel().send(orderMessage);
        requestChannel().send(inventoryMessage);
    }
    @Bean
    public org.springframework.messaging.MessageChannel requestChannel() {
        return new org.springframework.integration.channel.DirectChannel();
    }
}

四、动态路由与路由表

在某些复杂的集成场景中,路由规则可能需要根据运行时的条件动态变化,或者需要在配置文件中定义而不是硬编码在代码中。Spring Integration提供了动态路由的能力,允许开发人员在运行时修改路由规则或从外部配置中加载路由表。AbstractMappingMessageRouter是实现动态路由的基础类,它维护了一个通道映射表,可以在运行时更新。这种方式使得系统能够适应业务规则的变化,而无需修改代码和重新部署,提高了系统的灵活性和可维护性。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.router.AbstractMappingMessageRouter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.handler.annotation.Header;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@Configuration
public class DynamicRouterConfig {
    @Autowired
    private RoutingRuleService routingRuleService;
    // 自定义动态路由器
    @Bean
    @ServiceActivator(inputChanneandroidl = "dynamicRoutingChannel")
    public AbstractMappingMessageRouter dynamicRouter() {
        return new AbstractMappingMessageRouter() {
            @Override
            protected Collection<MessageChannel> determineTargetChannels(Message<?> message) {
                // 从服务中获取最新的路由规则
                Map<String, String> routingRules = routingRuleService.getRoutingRules();
                // 根据消息内容或头信息确定路由键
                String routingKey = extractRoutingKey(message);
                // 根据路由键查找目标通道名称
                String channelName = routingRules.getOrDefault(routingKey, "defaultChannel");
                // 获取目标通道并返回
                MessageChannel channel = getChannelResolver().resolveDestination(channelName);
                return Collections.singleton(channel);
            }
            private String extractRoutingKey(Message<?> message) {
                // 实现从消息中提取路由键的逻辑
                // 这里简化为从特定的消息头中获取
                return (String) message.getHeaders().get("routing-key");
            }
        };
    }
    // 路由规则服务,用于管理和提供路由规则
    @Bean
    public RoutingRuleService routingRuleService() {
        return new RoutingRuleService();
    }
    // 路由规则管理服务
    public static class RoutingRuleService {
        private Map<String, String> routingRules = new HashMap<>();
        public RoutingRuleService() {
            // 初始化默认路由规则
            routingRules.put("ORDER", "orderChannel");
            routingRules.put("INVENTORY", "inventoryChannel");
            routingRules.put("CUSTOMER", "customerChannel");
        }
        public Map<String, String> getRoutingRules() {
            return routingRules;
        }
        public void updateRoutingRule(String key, String channelName) {
            routingRules.put(key, channelName);
        }
        public void loadRoutingRules(Properties properties) {
            properties.forEach((k, v) -> routingRules.put(k.toString(), v.toString()));
        }
    }
    // 路由规则更新API
    @Bean
    @ServiceActivator(inputChannel = "routingRuleUpdateChannel")
    public void updateRoutingRule(Message<RoutingRuleUpdate> message) {
        RoutingRuleUpdate update = message.getPayload();
        routingRuleService.updateRoutingRule(update.getKey(), update.getChannelName());
    }
    // 路由规则更新请求
    public static class RoutingRuleUpdate {
        private String key;
        private String channelName;
        // 省略getter和setter
    }
}

五、消息过滤与选择性路由

消息过滤是路由的一种特殊形式,它基于特定条件决定是否允许消息继续流转。Spring Integration的Filter组件用于实现这一功能,它可以根据消息的内容或消息头信息过滤掉不符合条件的消息。过滤器可以作为独立的组件使用,也可以与路由器结合使用,实现更复杂的路由逻辑。例如,在处理订单消息时,可以过滤掉无效的订单,或者将不同类型的订单路由到不同的处理通道。这种选择性路由机制使得系统能够更有针对性地处理不同类型的消息,提高了处理效率和系统的可维护性。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.Filter;
import org.springframework.integration.annotation.Rojavascriptuter;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.core.MessageSelector;
import org.springframework.integration.router.RecipientListRouter;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
@Configuration
public class FilterAndSelectiveRoutingConfig {
    // 消息过滤器示例
    @Bean
    @Filter(inputChannel = "unfilteredChannel", outputChannel = "validOrderChannel")
    public MessageSelector orderValidator() {
        return message -> {
            Order order = (Order) message.getPayload();
            // 验证订单是否有效
            boolean isValid = order.getItems() != null && !order.getItems().isEmpty()
                    && order.getCustomerId() != null
                    && order.getTotalAmount() > 0;
            return isValid;
        };
    }
    // 结合过滤和路由的示例
    @Bean
    public org.springframework.integration.dsl.IntegrationFlow filterAndRouteFlow() {
        return org.springframework.integration.dsl.IntegrationFlows
                .from("inputOrderChannel")
                // 首先过滤无效订单
                .filter(message -> {
                    Order order = (Order) message.getPayload();
                    return order.isValid();
                })
                // 然后根据订单类型路由
                .<Order, String>route(
                        order -> order.getType(),
                        mapping -> mapping
                                .subFlowMapping("RETAIL", sf -> sf.channel("retailOrderChannel"))
                                .subFlowMapping("WHOLESALE", sf -> sf.channel("wholesaleOrderChannel"))
                                .subFlowMapping("ONLINE", sf -> sf.channel("onlineOrderChannel"))
                                .defaultSubFlowMapping(sf -> sf.channel("unknownOrderChannel"))
                )
                .get();
    }
    // 使用RecipientListRouter实现有条件的多通道路由
    @Bean
    @Router(inputChannel = "orderRoutingChannel")
    public RecipientListRouter orderRouter() {
        RecipientListRouter router = new RecipientListRouter();
        // 添加基于SpEL表达式的路由条件
        router.addRecipient("highValueOrderChannel", "payload.totalAmount > 1000");
        router.addRecipient("priorityCustomerOrderChannel", "payload.customerType == 'VIP'");
        router.addRecipient("internationalOrderChannel", "payload.shippingAddress.country != 'China'");
        // 将订单同时发送到审计通道
        router.addRecipient("orderAuditChannel");
        return router;
    }
    // 处理无效订单的示例
    @Bean
    @ServiceActivator(inputChannel = "invalidOrderChannel")
    public void handleInvalidOrder(Message<Order> message) {
        Order order = message.getPayload();
        // 记录无效订单
        System.out.println("无效订单: " + order.getOrderId());
        // 创建通知消息
        Message<String> notification = MessageBuilder
                .withPayload("订单 " + order.getOrderId() + " 验证失败")
                .setHeader("notification-type", "ORDER_VALIDATION_FAILURE")
                .setHeader("order-id", order.getOrderId())
                .build();
        // 发送通知
        notificationChannel().send(notification);
    }
    @Bean
    public org.springframework.messaging.MessageChannel notificationChannel() {
        return new org.springframework.integration.channel.DirectChannel();China编程
    }
    // 示例数据类
    public static class Order {
        private String orderId;
        private String customerId;
        private String customerType;
        private String type;
        private List<OrderItem> items;
        private double totalAmount;
        private Address shippingAddress;
        // 省略getter和setter
        public boolean isValid() {
   China编程         return items != null && !items.isEmpty()
                    && customerId != null
                    && totalAmount > 0;
        }
    }
    public static class OrderItem {
        private String productId;
        private int quantity;
        private double price;
        // 省略getter和setter
    }
    public static class Address {
        private String street;
        private String city;
        private String state;
        private String zipCode;
        private String country;
        // 省略getter和setter
    }
}

六、错误处理与路由

在企业集成中,错误处理是一个重要的考虑因素。Spring Integration提供了丰富的错误处理机制,包括错误通道、全局错误处理器和特定组件的错误处理配置。在路由过程中,可能会发生各种错误,如无法找到匹配的通道、消息处理异常等。通过配置错误通道和错误处理器,可以在发生错误时将消息路由到特定的错误处理流程,从而实现错误的集中处理和恢复。这种机制使得系统能够更加健壮地应对各种异常情况,提高了系统的可靠性和可用性。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer;
import org.springframework.integration.handler.advice.RequestHandlerRetryAdvice;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessagingException;
@Configuration
@IntegrationComponentScan
public class ErrorHandlingRouterConfig {
    // 定义错误通道
    @Bean
    public MessageChannel errorChannel() {
        return new DirectChannel();
    }
    // 定义主路由器流程,包含错误处理
    @Bean
    public IntegrationFlow routerWithErrorHandling() {
        return IntegrationFlows
                .from("inputChannel")
                .<Message<?>, String>route(
                        message -> {
                            try {
                                // 从消息中提取路由键
                                String type = (String) message.getHeaders().get("message-type");
                                if (type == null) {
                                    throw new IllegalArgumentException("消息类型不能为空");
                                }
                                return type;
                            } catch (Exception e) {
                                // 将异常信息放入消息头
                                throw new MessagingException(message, "路由错误: " + e.getMessage(), e);
                            }
                        },
                        mapping -> mapping
                                .subFlowMapping("ORDER", sf -> sf.channel("orderChannel"))
                                .subFlowMapping("INVENTORY", sf -> sf.channel("inventoryChannel"))
                                .defaultSubFlowMapping(sf -> sf.channel("unknownTypeChannel"))
                )
                // 配置错误通道
                .errorChannel("errorChannel")
                .get();
    }
    // 错误处理服务
    @Bean
    @ServiceActivator(inputChannel = "errorChannel")
    public void handleError(Message<MessagingException> errorMessage) {
        MessagingException exception = errorMessage.getPayload();
        Message<?> failedMessage = exception.getFailedMessage();
        System.err.println("处理消息时发生错误: " + exception.getMessage());
        System.err.println("失败的消息: " + failedMessage);
        // 根据异常类型执行不同的错误处理逻辑
        if (exception.getCause() instanceof IllegalArgumentException) {
            // 发送到无效消息通道
            invalidMessageChannel().send(MessageBuilder
                    .withPayload(failedMessage.getPayload())
                    .copyHeaders(failedMessage.getHeaders())
                    .setHeader("error-message", exception.getMessage())
                    .build());
        } else {
            // 发送到重试通道,尝试重新处理
            retryChannel().send(failedMessage);
        }
    }
    // 包含重试逻辑的路由器
    @Bean
    public IntegrationFlow retryableRouterFlow() {
        return IntegrationFlows
                .from("retryChannel")
                .<Object, String>route(
                        payload -> {
                            if (payload instanceof Order) {
                                return "orderChannel";
                            } else if (payload instanceof InventoryItem) {
                                return "inventoryChannel";
                            } else {
                                return "unknownTypeChannel";
                            }
                        },
                        // 应用重试通知
                        spec -> spec.advice(retryAdvice())
                )
                .get();
    }
    // 重试通知配置
    @Bean
    public RequestHandlerRetryAdvice retryAdvice() {
        RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();
        // 配置重试策略
        org.springframework.retry.support.RetryTemplate retryTemplate = new org.springframework.retry.support.RetryTemplate();
        // 设置重试策略:最多重试3次
        retryTemplate.setRetryPolicy(new org.springframework.retry.policy.SimpleRetryPolicy(3));
        // 设置退避策略:指数退避,初始1秒,最大30秒
        org.springframework.retry.backoff.ExponentialBackOffPolicy backOffPolicy = new org.springframework.retry.backoff.ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(1000);
        backOffPolicy.setMaxInterval(30000);
        backOffPolicy.setMultiplier(2.0);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        advice.setRetryTemplate(retryTemplate);
        // 设置恢复策略:发送到死信通道
        ErrorMessageSendingRecoverer recoverer = new ErrorMessageSendingRecoverer(deadLetterChannel());
        advice.setRecoveryCallback(recoverer);
        return advice;
    }
    // 定义死信通道
    @Bean
    public MessageChannel deadLetterChannel() {
        return new DirectChannel();
    }
    // 定义无效消息通道
    @Bean
    public MessageChannel invalidMessageChannel() {
        return new DirectChannel();
    }
    // 定义重试通道
    @Bean
    public MessageChannel retryChannel() {
        return new DirectChannel();
    }
    // 示例消息网关
    @MessagingGateway(defaultRequestChannel = "inputChannel")
    public interface MessageRoutingGateway {
        void send(Message<?> message);
    }
}

总结

Spring Integration的Router组件为企业应用集成提供了强大的消息路由能力,使得系统能够根据不同的条件灵活地处理消息流。本文详细介绍了Router的基础概念、条件路由实现、基于消息头的路由、动态路由与路由表、消息过滤与选择性路由以及错误处理与路由等方面的内容。这些技术为构建复杂的企业集成解决方案提供了有力的支持,使得系统的各个组件能够以松耦合的方式进行协作,提高了系统的可维护性和可扩展性。在实际应用中,开发人员可以根据具体需求选择合适的路由策略,通过组合使用多种路由机制,构建灵活、健壮的消息处理流程。

到此这篇关于SpringIntegration消息路由之Router的条件路由与过滤的文章就介绍到这了,更多相关SpringIntegration消息路由内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于SpringIntegration消息路由之Router的条件路由与过滤功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154051

相关文章

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

基于SpringBoot实现文件秒传功能

《基于SpringBoot实现文件秒传功能》在开发Web应用时,文件上传是一个常见需求,然而,当用户需要上传大文件或相同文件多次时,会造成带宽浪费和服务器存储冗余,此时可以使用文件秒传技术通过识别重复... 目录前言文件秒传原理代码实现1. 创建项目基础结构2. 创建上传存储代码3. 创建Result类4.

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

java streamfilter list 过滤的实现

《javastreamfilterlist过滤的实现》JavaStreamAPI中的filter方法是过滤List集合中元素的一个强大工具,可以轻松地根据自定义条件筛选出符合要求的元素,本文就来... 目录1. 创建一个示例List2. 使用Stream的filter方法进行过滤3. 自定义过滤条件1. 定

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

Python实战之屏幕录制功能的实现

《Python实战之屏幕录制功能的实现》屏幕录制,即屏幕捕获,是指将计算机屏幕上的活动记录下来,生成视频文件,本文主要为大家介绍了如何使用Python实现这一功能,希望对大家有所帮助... 目录屏幕录制原理图像捕获音频捕获编码压缩输出保存完整的屏幕录制工具高级功能实时预览增加水印多平台支持屏幕录制原理屏幕

Python实现自动化表单填写功能

《Python实现自动化表单填写功能》在Python中,自动化表单填写可以通过多种库和工具实现,本文将详细介绍常用的自动化表单处理工具,并对它们进行横向比较,可根据需求选择合适的工具,感兴趣的小伙伴跟... 目录1. Selenium简介适用场景示例代码优点缺点2. Playwright简介适用场景示例代码

MySQL中闪回功能的方案讨论及实现

《MySQL中闪回功能的方案讨论及实现》Oracle有一个闪回(flashback)功能,能够用户恢复误操作的数据,这篇文章主要来和大家讨论一下MySQL中支持闪回功能的方案,有需要的可以了解下... 目录1、 闪回的目标2、 无米无炊一3、 无米无炊二4、 演示5、小结oracle有一个闪回(flashb

MySQL使用binlog2sql工具实现在线恢复数据功能

《MySQL使用binlog2sql工具实现在线恢复数据功能》binlog2sql是大众点评开源的一款用于解析MySQLbinlog的工具,根据不同选项,可以得到原始SQL、回滚SQL等,下面我们就来... 目录背景目标步骤准备工作恢复数据结果验证结论背景生产数据库执行 SQL 脚本,一般会经过正规的审批