Spring Boot中RedisAutoConfiguration的自动配置原理与实践
1. RedisAutoConfiguration 的核心作用与设计理念RedisAutoConfiguration 是 Spring Boot 自动配置体系中对 Redis 支持的实现核心。当我们在项目中引入 spring-boot-starter-data-redis 依赖时这个自动配置类就会生效。它的核心价值在于通过约定大于配置的原则让开发者用最少的代码快速集成 Redis 功能。这个自动配置类有几个关键设计特点条件化装配通过 ConditionalOnClass 注解确保只有在类路径下存在 RedisOperations 类时才生效多连接器支持通过 Import 同时引入了 Lettuce 和 Jedis 两种连接方案的配置类模板注入自动提供了 RedisTemplate 和 StringRedisTemplate 两种常用操作模板在实际项目中我们只需要在 application.properties 中配置 redis.host 等基本参数就可以直接注入 RedisTemplate 使用省去了大量样板代码的编写。这种设计体现了 Spring Boot开箱即用的理念。2. 自动配置的触发条件与流程解析2.1 自动配置的触发条件链RedisAutoConfiguration 的生效不是无条件的它依赖于一系列条件注解的控制Configuration ConditionalOnClass(RedisOperations.class) EnableConfigurationProperties(RedisProperties.class) Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }) public class RedisAutoConfiguration { //... }这个条件链的工作逻辑是首先检查类路径中是否存在 RedisOperations 类来自 spring-data-redis然后启用 RedisProperties 配置绑定功能最后导入两种连接器配置Lettuce 和 Jedis2.2 连接器选择机制Spring Boot 会按以下顺序确定使用哪种 Redis 连接器如果检测到 Lettuce 在类路径中优先使用 LettuceConnectionConfiguration如果检测到 Jedis 在类路径中且没有 Lettuce则使用 JedisConnectionConfiguration如果两者都存在默认优先选择 Lettuce从 Spring Boot 2.0 开始这种设计使得开发者可以通过简单的依赖管理来控制底层连接器的选择。例如要强制使用 Jedis可以在 pom.xml 中排除 Lettucedependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId exclusions exclusion groupIdio.lettuce/groupId artifactIdlettuce-core/artifactId /exclusion /exclusions /dependency3. 核心组件初始化过程3.1 RedisTemplate 的自动配置RedisAutoConfiguration 中最重要的方法就是 redisTemplate()Bean ConditionalOnMissingBean(name redisTemplate) public RedisTemplateObject, Object redisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplateObject, Object template new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; }这个方法有几个关键点使用 ConditionalOnMissingBean 确保只有在容器中不存在名为 redisTemplate 的 Bean 时才会创建接收一个 RedisConnectionFactory 参数由 Lettuce 或 Jedis 配置类提供创建基本的 RedisTemplate 实例并配置连接工厂3.2 StringRedisTemplate 的特殊处理除了通用的 RedisTemplate自动配置还提供了专门处理字符串的 StringRedisTemplateBean ConditionalOnMissingBean public StringRedisTemplate stringRedisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { StringRedisTemplate template new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; }StringRedisTemplate 与普通 RedisTemplate 的主要区别在于默认使用 StringRedisSerializer 作为键和值的序列化器更适合处理纯字符串场景不需要指定泛型类型4. 配置属性与自定义扩展4.1 RedisProperties 配置项解析RedisAutoConfiguration 通过 EnableConfigurationProperties(RedisProperties.class) 启用了配置属性绑定。RedisProperties 中定义了所有可配置的 Redis 参数# 基本连接配置 spring.redis.hostlocalhost spring.redis.port6379 spring.redis.password spring.redis.database0 # 连接池配置适用于Jedis spring.redis.jedis.pool.max-active8 spring.redis.jedis.pool.max-idle8 spring.redis.jedis.pool.min-idle0 # 连接超时配置 spring.redis.timeout20004.2 自定义 RedisTemplate 配置虽然自动配置提供了默认的 RedisTemplate但在实际项目中我们通常需要自定义序列化方式。可以通过以下方式覆盖默认配置Configuration public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate( RedisConnectionFactory redisConnectionFactory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 Jackson2JsonRedisSerializerObject serializer new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.activateDefaultTyping( mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(mapper); template.setValueSerializer(serializer); template.setKeySerializer(new StringRedisSerializer()); return template; } }这种自定义配置会优先于自动配置生效因为它的 Bean 名称也是 redisTemplate通过方法名隐式指定。5. 生产环境中的最佳实践5.1 连接池配置优化在生产环境中合理的连接池配置对性能至关重要。以 Lettuce 为例推荐配置如下# Lettuce 连接池配置 spring.redis.lettuce.pool.enabledtrue spring.redis.lettuce.pool.max-active16 spring.redis.lettuce.pool.max-idle8 spring.redis.lettuce.pool.min-idle4 spring.redis.lettuce.pool.max-wait1000 spring.redis.lettuce.shutdown-timeout100关键参数说明max-active最大连接数根据并发量调整max-idle最大空闲连接数建议设为 max-active 的 50%min-idle最小空闲连接数避免频繁创建新连接max-wait获取连接的最大等待时间毫秒5.2 高可用与集群配置对于 Redis 集群或哨兵模式可以通过以下配置实现自动发现# 哨兵模式配置 spring.redis.sentinel.mastermymaster spring.redis.sentinel.nodes192.168.1.1:26379,192.168.1.2:26379 # 集群模式配置 spring.redis.cluster.nodes192.168.1.1:6379,192.168.1.2:6379 spring.redis.cluster.max-redirects35.3 监控与健康检查Spring Boot Actuator 提供了 Redis 的健康检查端点。要启用它需要添加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency然后在 application.properties 中配置management.endpoint.health.show-detailsalways management.endpoints.web.exposure.includehealth访问 /actuator/health 可以看到 Redis 的连接状态。6. 常见问题排查与解决方案6.1 连接超时问题当出现连接超时错误时可以按照以下步骤排查检查网络连通性使用 telnet 或 redis-cli 测试是否能连接到 Redis 服务器检查防火墙设置确保 Redis 端口默认 6379没有被防火墙拦截检查 Redis 配置确认 redis.conf 中的 bind 和 protected-mode 设置正确调整超时参数适当增加 spring.redis.timeout 值6.2 序列化异常处理在使用 RedisTemplate 时常见的序列化异常包括java.lang.ClassCastException通常是因为存储和读取时使用了不同的序列化器com.fasterxml.jackson.databind.exc.InvalidTypeIdExceptionJSON 反序列化时类型信息丢失解决方案确保读写操作使用相同的 RedisTemplate 配置为复杂对象配置正确的类型信息使用 Class 注解或 ObjectMapper 的 activateDefaultTyping考虑使用 StringRedisTemplate 配合手动 JSON 序列化6.3 Lettuce 与 Jedis 的选择考量两种连接器的对比特性LettuceJedis连接模型基于 Netty 的异步非阻塞阻塞式同步连接线程安全是单个连接不安全需用连接池集群支持内置完善支持需要额外配置性能高并发场景更优简单场景延迟更低资源消耗较低较高活跃度维护活跃维护模式选择建议新项目推荐使用 Lettuce特别是需要高并发的场景现有使用 Jedis 的项目可以继续使用但建议逐步迁移需要同步阻塞操作的特殊场景可以考虑 Jedis7. 高级特性与原理深度解析7.1 自动配置的条件评估机制Spring Boot 的自动配置是通过条件评估机制实现的。对于 RedisAutoConfiguration关键的条件评估包括类路径条件检查 RedisOperations 类是否存在Bean 条件检查是否已存在 RedisTemplate 或 StringRedisTemplate配置条件检查是否有相关的配置属性这些条件的评估是通过 ConditionEvaluator 在配置类解析阶段完成的。可以通过启动日志查看条件匹配情况logging.level.org.springframework.boot.autoconfigureDEBUG在日志中可以看到类似这样的输出RedisAutoConfiguration matched: - ConditionalOnClass found required class org.springframework.data.redis.core.RedisOperations (OnClassCondition)7.2 连接工厂的创建过程RedisConnectionFactory 的创建是自动配置的核心环节。以 Lettuce 为例创建过程如下LettuceConnectionConfiguration 读取 RedisProperties 配置根据配置创建 ClientResources共享资源创建 LettuceClientConfiguration客户端配置使用 RedisStandaloneConfiguration/RedisClusterConfiguration 创建连接工厂如果启用了连接池会包装成 LettucePoolingClientConfiguration这个过程充分体现了 Spring Boot 的分层配置理念每一层都可以通过配置或代码进行定制。7.3 模板类的扩展点虽然 RedisAutoConfiguration 提供了基本的 RedisTemplate但 Spring Data Redis 还提供了多种扩展点RedisRepository类似 JPA 的 Repository 接口RedisCacheManager与 Spring Cache 集成RedisMessageListenerContainer用于 Pub/Sub 模式RedisScript支持 Lua 脚本执行这些扩展点可以与自动配置无缝集成只需要添加相应的配置即可。8. 性能调优实战经验8.1 连接池参数优化实践经过多个生产项目的实践总结出以下连接池优化经验最大连接数max-active设置低并发8-16中等并发16-32高并发32-64需考虑 Redis 服务器性能最大空闲连接max-idle建议设置为 max-active 的 50-70%最小空闲连接min-idle建议设置为 max-idle 的 50%获取连接超时时间max-wait建议设置一般场景1秒高延迟网络2-3秒绝对不能设置为-1无限等待8.2 序列化方案性能对比我们对几种常见序列化方案进行了性能测试测试环境Redis 6.0Java 11序列化方式写入耗时(ms)读取耗时(ms)数据大小(bytes)JDK 序列化4552885Jackson JSON2835423Kryo1518287StringRedisSerializer53原始大小选择建议纯字符串场景优先使用 StringRedisSerializer复杂对象推荐使用 Jackson JSON极致性能场景考虑 Kryo但要注意类型兼容性问题8.3 Pipeline 批量操作优化对于批量操作使用 Pipeline 可以显著提升性能。示例代码ListObject results redisTemplate.executePipelined( (RedisCallbackObject) connection - { for (int i 0; i 1000; i) { connection.stringCommands().set( (key: i).getBytes(), (value: i).getBytes() ); } return null; } );实测对比普通循环设置1000个键值1200ms使用 Pipeline 设置1000个键值85ms注意事项Pipeline 中的操作数量不宜过多建议不超过5000要确保单次 Pipeline 的数据量不会导致内存溢出某些 Redis 集群模式可能对 Pipeline 支持有限9. 与其他技术的整合实践9.1 与 Spring Cache 集成RedisAutoConfiguration 为 Spring Cache 提供了开箱即用的支持添加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-cache/artifactId /dependency启用缓存SpringBootApplication EnableCaching public class MyApplication { // ... }配置 Redis 缓存spring.cache.typeredis spring.cache.redis.time-to-live600000 spring.cache.redis.key-prefixmyapp: spring.cache.redis.cache-null-valuesfalse使用缓存注解Service public class ProductService { Cacheable(value products, key #id) public Product getProductById(Long id) { // ... } }9.2 与 Spring Session 集成使用 Redis 存储 HTTP Session添加依赖dependency groupIdorg.springframework.session/groupId artifactIdspring-session-data-redis/artifactId /dependency配置 Session 存储spring.session.store-typeredis spring.session.redis.flush-modeon_save spring.session.redis.namespacespring:session自定义 Session 配置Configuration EnableRedisHttpSession public class SessionConfig extends AbstractHttpSessionConfiguration { Bean public RedisSerializerObject springSessionDefaultRedisSerializer() { return new GenericJackson2JsonRedisSerializer(); } }9.3 与 Spring Security 整合将 Redis 用于 Spring Security 的 Remember-Me 功能配置 Remember-Me 持久化Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { Autowired private RedisConnectionFactory redisConnectionFactory; Override protected void configure(HttpSecurity http) throws Exception { http.rememberMe() .rememberMeServices(rememberMeServices()); } Bean public PersistentTokenRepository rememberMeServices() { RedisTokenRepositoryImpl repository new RedisTokenRepositoryImpl(); repository.setRedisConnectionFactory(redisConnectionFactory); return repository; } }自定义 Token 存储实现public class RedisTokenRepositoryImpl implements PersistentTokenRepository { private final RedisTemplateString, Object redisTemplate; public RedisTokenRepositoryImpl(RedisConnectionFactory connectionFactory) { this.redisTemplate new RedisTemplate(); redisTemplate.setConnectionFactory(connectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); } // 实现接口方法... }10. 测试策略与模拟方案10.1 单元测试中的 Redis 模拟对于不依赖 Redis 特定功能的测试可以使用 mock 方式SpringBootTest AutoConfigureMockMvc public class ProductControllerTest { MockBean private RedisTemplateString, Object redisTemplate; Test public void testGetProduct() throws Exception { Product mockProduct new Product(1L, Test Product); when(redisTemplate.opsForValue().get(anyString())) .thenReturn(mockProduct); // 执行测试断言... } }10.2 集成测试使用嵌入式 Redis对于需要真实 Redis 功能的测试可以使用嵌入式 Redis添加测试依赖dependency groupIdit.ozimov/groupId artifactIdembedded-redis/artifactId version0.7.3/version scopetest/scope /dependency配置测试 RedisSpringBootTest Testcontainers public class RedisIntegrationTest { Container private static final GenericContainer? redis new GenericContainer(redis:6-alpine) .withExposedPorts(6379); DynamicPropertySource static void redisProperties(DynamicPropertyRegistry registry) { registry.add(spring.redis.host, redis::getHost); registry.add(spring.redis.port, redis::getFirstMappedPort); } // 测试方法... }10.3 测试切片的使用对于只测试 Redis 相关功能的场景可以使用 DataRedisTestDataRedisTest public class RedisRepositoryTest { Autowired private RedisTemplateString, Object redisTemplate; Test public void testSaveAndGet() { String key test:key; String value test value; redisTemplate.opsForValue().set(key, value); String retrieved (String) redisTemplate.opsForValue().get(key); assertEquals(value, retrieved); } }这种测试切片只会加载 Redis 相关的自动配置使测试更加专注和快速。

相关新闻

手机隐私保护:如何防止应用后台监听与数据泄露

手机隐私保护:如何防止应用后台监听与数据泄露

1. 手机隐私保护现状与潜在风险最近三年内,全球移动应用隐私合规问题数量增长了217%。我在做手机安全检测时发现,90%的安卓应用存在过度权限申请的情况,其中麦克风权限滥用最为普遍。上周帮朋友排查手机耗电异常时,就发现某款壁纸…

2026/7/26 20:50:02 阅读更多 →
政治人物情绪管理:杰克逊大法官听证会落泪事件分析

政治人物情绪管理:杰克逊大法官听证会落泪事件分析

1. 事件背景与核心场景还原2022年3月21日,美国最高法院大法官提名人凯坦吉布朗杰克逊(Ketanji Brown Jackson)在参议院司法委员会听证会上情绪激动落泪。这个持续四天的确认听证会,因其特殊历史意义和激烈质询过程成为全球焦点。作…

2026/8/1 8:41:51 阅读更多 →
C++并发编程实战:从进程线程原理到线程池实现

C++并发编程实战:从进程线程原理到线程池实现

1. 项目概述:为什么并发编程是C开发者的必修课?如果你写过C程序,大概率遇到过这样的场景:一个数据处理任务,面对海量文件,单线程跑起来要几个小时,界面卡死,用户疯狂点击。或者&…

2026/8/1 10:17:14 阅读更多 →

最新新闻

兼容性还是安全性?一个关于 Fastjson 的十年之问

兼容性还是安全性?一个关于 Fastjson 的十年之问

兼容性还是安全性?一个关于 Fastjson 的十年之问在软件工程的世界里,框架设计者时常会面对一道艰难的选择题:当兼容性与安全性发生冲突时,应该站在哪一边?Fastjson 的十年漏洞史,恰好为这道题提供了一个血淋…

2026/8/1 19:04:28 阅读更多 →
九大网盘直链下载助手:告别限速,实现真正的高速下载体验

九大网盘直链下载助手:告别限速,实现真正的高速下载体验

九大网盘直链下载助手:告别限速,实现真正的高速下载体验 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移…

2026/8/1 19:04:28 阅读更多 →
吐血整理深度学习入门路线及导航【教学视频+大神博客+书籍整理】+【资源页】(2019年已经最后一个月了,你还不学深度学习吗???)

吐血整理深度学习入门路线及导航【教学视频+大神博客+书籍整理】+【资源页】(2019年已经最后一个月了,你还不学深度学习吗???)

声明: 1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献。 2)本文仅供学术交流,非商用。所以每一部分具体的参考资料并没有详细对应。如果某部分不小心侵犯了大家的利益&#xff0c…

2026/8/1 19:04:28 阅读更多 →
混沌工程终极指南:5分钟掌握ChaosBlade无侵入式故障注入

混沌工程终极指南:5分钟掌握ChaosBlade无侵入式故障注入

混沌工程终极指南:5分钟掌握ChaosBlade无侵入式故障注入 【免费下载链接】chaosblade An easy to use and powerful chaos engineering experiment toolkit.(阿里巴巴开源的一款简单易用、功能强大的混沌实验注入工具) 项目地址: https://g…

2026/8/1 19:03:27 阅读更多 →
Joplin终极指南:如何快速搭建隐私优先的笔记应用开发环境

Joplin终极指南:如何快速搭建隐私优先的笔记应用开发环境

Joplin终极指南:如何快速搭建隐私优先的笔记应用开发环境 【免费下载链接】joplin Joplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS. 项目地址: https://gitcode.com/GitHub_Trending/jo/jopli…

2026/8/1 19:03:27 阅读更多 →
Windows ADB驱动一键安装:3分钟搞定Android连接问题的终极方案

Windows ADB驱动一键安装:3分钟搞定Android连接问题的终极方案

Windows ADB驱动一键安装:3分钟搞定Android连接问题的终极方案 【免费下载链接】Latest-adb-fastboot-installer-for-windows A Simple Android Driver installer tool for windows (Always installs the latest version) 项目地址: https://gitcode.com/gh_mirro…

2026/8/1 19:03:27 阅读更多 →

日新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/8/1 13:02:46 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/8/1 5:19:34 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/8/1 10:33:33 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →