
Spring Boot
文章平均质量分 91
SpringBoot是Spring框架的扩展,其设计目的是用来简化Spring应用的初始搭建以及开发过程,使得开发变得更快、更高效、更自动化。
pan_junbiao
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
SpringBoot使用ThreadLocal保存登录用户信息
ThreadLocal 是 Java 中解决多线程数据隔离问题的工具,其核心功能是:每个线程拥有独立的变量副本,避免线程间共享数据导致的并发安全问题。java.lang.ThreadLocal 是自 JDK1.2 版本起提供的线程成员操作类,在多线程环境下开发工作中,经常需要区分不同的线程,而且在一个线程的执行过程中能够一直访问某一个数据,而 ThreadLocal 就是可以很好地解决这个问题。原创 2025-05-29 17:39:13 · 1167 阅读 · 4 评论 -
SpringBoot整合POI实现Excel文件的导出与导入
Apache POI 是一个基于 Java 的开源库,专为读写 Microsoft Office 格式文件(如 Excel、Word、PowerPoint、Visio 等)而设计,支持 Office 97-2016 版本的文件操作。其名称源于“Poor Obfuscation Implementation”(简洁版的模糊实现)的首字母缩写。Apache POI 功能全面,覆盖 Office 文件的全生命周期操作。社区活跃,文档丰富,适用于复杂场景(如:模板替换、动态生成报表)。原创 2025-04-15 20:06:07 · 1227 阅读 · 0 评论 -
SpringBoot使用Logback日志框架与综合实例
Spring Boot 支持很多种日志框架。通常情况下,这些日志框架是由一个日志抽象层和一个日志实现层搭建而成的。日志抽象层是为记录日志提供的一套标准且规范的框架,其作用在于为记录日志提供接口。日志实现层是由日志抽象层实现的框架。Spring Boot 默认使用的日志抽象层是 Slf4j,默认使用的日志实现层是 Logback 框架。Slf4j 是当下主流的日志抽象层。原创 2025-03-12 17:51:03 · 995 阅读 · 0 评论 -
SpringBoot使用Servlet监听器(Listener):Listener接口、@WebListener注释
在 Servlet 技术中已经定义了一些事件,并且可以针对这些事件来编写相关的事件监听器,从而对事件做出相应处理。例如,想要在 Web 应用程序启动和关闭时执行一些任务(如数据库连接的建立和释放),或者想要监听Session的创建和销毁,那么就可以通过监听器来实现。监听器的作用是监听 Web 容器的有效期事件,因此它是由容器管理的。利用 Listener 接口监听在容器中的某个执行程序,并且根据其应用程序的需求做出适当的响应。原创 2019-03-11 18:05:01 · 942 阅读 · 0 评论 -
SpringBoot设置过滤器(Filter)或拦截器(Interceptor)的执行顺序:@Order注解、setOrder()方法
在 Spring Boot 中,你可以使用 @Order 注解来设置过滤器(Filter)或拦截器(Interceptor)在过滤器链或拦截器链中的执行顺序。@Order 注解是 Spring 框架提供的一个用于定义组件加载或执行顺序的注解。它可以应用于任何由 Spring 容器管理的组件上,当你需要在多个组件之间定义一个明确的加载或执行顺序时,可以使用 @Order 注解。它接受一个整型值作为参数,该值越小,组件的优先级越高,即越早被加载或执行。原创 2025-03-10 18:44:34 · 863 阅读 · 0 评论 -
SpringBoot使用OncePerRequestFilter过滤器:确保一次请求只通过一次过滤器
OncePerRequestFilter 是 Spring 框架提供的一种过滤器实现,确保外部请求只执行一次过滤逻辑,避免服务器内部 forward 导致的重复过滤。因此,不需要担心在请求处理过程中过滤器会被多次调用。特别需要注意的是,在使用 Spring Security 过程中,Spring Security 中的 Filter 被加载了两次或多次的情况;如果想解决某些过滤器 Filter 只执行一次,可以采用SpringBoot官网提供的此方案。原创 2025-03-10 17:50:59 · 602 阅读 · 0 评论 -
SpringBoot过滤器(Filter)的使用:Filter接口、FilterRegistrationBean类配置、@WebFilter注释
Spring Boot 的过滤器用于对数据进行过滤处理。通过 Spring Boot 的过滤器,程序开发人员不仅可以对用户通过 URL 地址发送的请求进行过滤处理(例如:过滤一些错误的请求或者请求中的敏感词等),而且可以对服务器返回的数据进行过滤处理(例如:压缩响应信息等)。在 Web 服务器中部署了过滤器以后,不仅客户端发送的请求会经过过滤器的处理,而且请求在发送到目标资源处理以后,请求的回应信息也同样要经历过滤器。原创 2025-03-08 20:04:21 · 1130 阅读 · 0 评论 -
SpringBoot获取YAML配置文件中的属性值(二):使用Environment环境组件读取值
Spring Boot 提供的 Environment 接口提供了一种机制,使得应用程序能够轻松地获取和操作配置属性。这些属性通常来源于不同的渠道,如命令行参数、系统环境变量、配置文件(如:application.properties 或 application.yml )等,这些配置文件可以放置在不同的位置,如项目的classpath、文件系统或外部存储等。Environment 允许为不同的环境配置不同的 Profile,例如:dev(开发)、test(测试)、prod(生产)等。原创 2025-03-04 17:40:30 · 397 阅读 · 0 评论 -
SpringBoot整合SpringSecurity、MyBatis-Plus综合实例:认证、授权
Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架,它是 Spring 项目组中用来提供安全认证服务的框架,能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案。Spring Security 的前身是 Acegi Security。它是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架。Spring Security 采用了 AOP(面向切面编程)思想,并基于 Servlet 过滤器实现。原创 2025-02-27 17:45:56 · 1180 阅读 · 0 评论 -
SpringBoot整合SpringSecurity实现一个简单的认证与授权应用
Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架,它是 Spring 项目组中用来提供安全认证服务的框架,能够为基于 Sprin g的企业应用系统提供声明式的安全访问控制解决方案。Spring Security 的前身是 Acegi Security。它是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架。Spring Security 采用了 AOP(面向切面编程)思想,并基于 Servlet 过滤器实现。原创 2024-11-23 17:38:29 · 1178 阅读 · 0 评论 -
SpringBoot使用@Validated注解实现参数的验证
@Validated 注解是 Spring 框架中用于数据验证的强大工具,它可以与 JSR-303/349/380 注解结合使用,提供灵活的验证机制。通过合理使用 @Validated 注解,你可以确保应用程序中的数据正确性和一致性,从而提高应用程序的健壮性和用户体验。原创 2024-11-18 18:04:46 · 953 阅读 · 0 评论 -
SpringBoot使用AspectJ的@Around注解实现AOP全局记录接口:请求日志、响应日志、异常日志
@Around 是 AspectJ 框架中用于环绕通知(Around Advice)的注解。环绕通知是一种非常强大的通知类型,它允许你在目标方法执行前后插入自定义的行为,甚至可以决定是否继续执行目标方法或替换其返回值。使用 @Around 注解时,需要注意以下几点:异常处理:在环绕通知中,你必须处理或重新抛出任何在 joinPoint.proceed() 调用中抛出的异常。性能影响:由于环绕通知可以在方法执行前后执行自定义逻辑,因此可能会对性能产生影响。在性能敏感的应用中,应谨慎使用。原创 2024-11-16 19:09:56 · 795 阅读 · 0 评论 -
SpringBoot使用AspectJ实现AOP记录接口:请求日志、响应日志、异常日志
AspectJ 是一个面向切面的框架,它扩展了 Java 语言,并定义了 AOP(面向切面编程)语法。AspectJ 作为 AOP 的具体实现之一,向 Java 中加入了连接点(Join Point)这个新概念,以及切点(pointcut)、通知(Advice)、类型间声明(Inter-type declaration)和方面(Aspect)等新结构。这些新结构使得AspectJ能够处理那些使用传统的面向对象编程方法难以解决的问题,如横切关注点(如安全性、日志记录、事务管理等)的模块化。原创 2024-11-16 11:17:38 · 1129 阅读 · 0 评论 -
SpringBoot创建Cookie工具类实现Cookie的:写入、读取、删除
Cookie 是网站服务器发送到客户端(通常是浏览器)的一小段数据,用于在客户端存储用户信息,以便在用户再次访问网站时提供更好的体验。当用户在浏览器中访问某个网站时,服务器可能会在用户的计算机上创建一个 Cookie。这个 Cookie 包含了服务器的某些信息,如用户的登录状态、个性化设置等。当用户再次访问该网站时,浏览器会自动将这些 Cookie 发送给服务器,服务器通过读取这些信息来识别用户并提供相应的服务。原创 2024-11-14 17:50:40 · 861 阅读 · 0 评论 -
SpringBoot获取resources目录下的文件
在 Spring Boot 项目中,获取 resources 目录中的文件路径通常涉及到访问类路径资源(classpath resources)。Spring Boot 提供了一些工具类和方法,可以方便地访问这些资源。ApplicationContext 是 Spring 框架中的一个核心接口,它是 Spring IoC 容器的实现之一,用于管理和组织应用程序中的各种 Bean,同时提供了一系列功能来支持依赖注入、AOP 等特性。同时ApplicationContext 提供了对资源的访问能力,如文件、U原创 2024-10-30 17:55:40 · 921 阅读 · 0 评论 -
SpringBoot使用RestTemplate实现发送HTTP请求
RestTemplate 是 Spring 框架提供的一个用于访问 RESTful 服务的客户端工具,它简化了与 RESTful 服务的交互,并提供了一系列方便的方法来发送 HTTP 请求、处理响应以及处理错误。RestTemplate 提供了一组简单易用的方法,使得发送HTTP请求变得非常简单和直观。RestTemplate 可以自动将请求和响应的 JSON/XML 数据转换为 Java 对象,简化了数据的处理过程。原创 2024-10-19 18:06:22 · 1664 阅读 · 0 评论 -
SpringBoot实现接口:统一返回值、全局异常处理、Swagger接口文档
在 Spring Boot 应用中实现统一返回值和全局异常处理可以带来多方面的好处,这些好处不仅提升了代码的可读性和可维护性,还增强了应用的健壮性和用户体验。通过定义统一的返回值格式,可以确保整个应用中的API响应结构保持一致。统一的异常处理机制使得错误信息的返回方式也保持一致,便于前端开发者理解和处理。原创 2024-10-15 16:28:50 · 1227 阅读 · 0 评论 -
SpringBoot使用@Slf4j注解实现日志输出
@Slf4j 是 Lombok 库中的一个注解,它极大地简化了日志记录的代码。通过使用这个注解,Lombok 会自动在你的类中注入一个静态的日志对象。通过在类上添加 @Slf4j 注解后,可以直接在方法中使用 log.info() 等方法进行日志打印。原创 2024-09-29 16:50:55 · 952 阅读 · 0 评论 -
SpringBoot解决跨域问题
在 Spring Boot 项目中解决跨域问题,主要可以通过以下几种方式来实现。使用 @CrossOrigin 注解,是 Spring 4.2 后引入的。这是解决跨域问题最直接和简单的方法,@CrossOrigin 注解可以添加到类或者方法上,以允许跨域请求。通过实现 WebMvcConfigurer 接口,并重写 addCorsMappings 方法来实现解决跨域问题,这种方式提供了更灵活的配置选项,实现全局的跨域配置。原创 2024-09-29 14:58:09 · 1402 阅读 · 0 评论 -
SpringBoot与MyBatis-Plus的整合与综合实例
MyBatis 是一款优秀的持久层框架,它支持定制化SQL、存储过程、以及高级映射。MyBatis3 提供的注解可以取代 XML。例如,使用注解 @Select 直接编写 SQL 完成数据查询。MyBatis-Plus 是一个对 MyBatis 进行增强的工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。原创 2024-09-27 17:48:16 · 1471 阅读 · 0 评论 -
SpringBoot整合Lombok插件与使用说明
Lombok 是一款 Java 开发插件,旨在通过定义的一些注解来消除业务工程中冗长和繁琐的代码,尤其是对于简单的 Java 模型对象(POJO)。使用 Lombok 插件后,Java 开发人员可以节省出重复构建诸如 hashCode 和 equals 这样的方法以及各种业务对象模型的 accessor 和 ToString 等方法的大量时间。这些方法在编译源代码期间自动生成,并没有如反射那样降低程序的性能。原创 2024-09-26 18:54:31 · 1325 阅读 · 0 评论 -
SpringBoot使用拦截器(Interceptor)实现用户登录校验
在系统中,经常需要在处理用户请求之前和之后执行一些行为,例如检测用户的权限,或者将请求的信息记录到日志中。当然不仅仅这些,所以需要一种机制,拦截用户的请求,在请求的前后添加处理逻辑。SpringBoot 提供了 Interceptor 拦截器机制,用于请求的预处理和后处理。在 SpringBoot 中定义一个拦截器有两种方法:第一种是实现 HandlerInterceptor 接口,或者继承实现了 HandlerInterceptor 接口的类(例如:HandlerInterceptorAdapter)。原创 2021-10-11 17:21:31 · 18472 阅读 · 0 评论 -
SpringBoot通过重写WebMvcConfigurer配置接口中的addViewControllers方法实现页面跳转
WebMvcConfigurer 配置接口其实是 Spring 内部的一种配置方式,采用 JavaBean 的形式来代替传统的 XML 配置文件形式进行针对框架个性化定制,可以自定义一些 Handler,Interceptor,ViewResolver,MessageConverter。基于 java-based 方式的 Spring MVC 配置,需要创建一个配置类并实现 WebMvcConfigurer接口。了解WebMvcConfigurer配置接口的详解:请浏览本博客的文章:《Sprin.原创 2021-09-01 16:58:11 · 3447 阅读 · 1 评论 -
SpringBoot中的WebMvcConfigurer配置接口的详解
1. 简介WebMvcConfigurer 配置接口其实是 Spring 内部的一种配置方式,采用 JavaBean 的形式来代替传统的 XML 配置文件形式进行针对框架个性化定制,可以自定义一些 Handler,Interceptor,ViewResolver,MessageConverter。基于 java-based 方式的 Spring MVC 配置,需要创建一个配置类并实现 WebMvcConfigurer接口。转载 2021-09-01 15:27:01 · 3559 阅读 · 0 评论 -
SpringBoot整合Elasticsearch与综合实例(二):搜索、分页、排序
Elasticsearch 是一个分布式、可扩展、近实时的高性能搜索与数据分析引擎。Elasticsearch 基于 Apache Lucene 构建,采用 Java 编写,并使用 Lucene 构建索引、提供搜索功能。Elasticsearch 的目标是让全文搜索功能的落地变得简单。本文是SpringBoot整合Elasticsearch与综合实例的第二篇,主要实现SpringBoot整合Elasticsearch实现搜索、分页、排序的相关操作。SpringBoot整合Elasticsearch原创 2021-05-15 15:57:44 · 2891 阅读 · 2 评论 -
SpringBoot整合Elasticsearch与综合实例(一):索引、文档
Elasticsearch 是一个分布式、可扩展、近实时的高性能搜索与数据分析引擎。Elasticsearch 基于 Apache Lucene 构建,采用 Java 编写,并使用 Lucene 构建索引、提供搜索功能。Elasticsearch 的目标是让全文搜索功能的落地变得简单。本文是SpringBoot整合Elasticsearch与综合实例的第一篇,主要实现SpringBoot整合Elasticsearch实现索引和文档的相关操作。SpringBoot整合Elasticsearch与综合原创 2021-05-13 15:54:30 · 1530 阅读 · 0 评论 -
SpringBoot整合RabbitMQ实现消息的发送与接收
RabbitMQ 是采用 Erlang 语言实现 AMQP(Advanced Message Queuing Protocol,高级消息队列协议)的消息中间件,用于在分布式系统中存储转发消息。RabbitMQ 凭借其高可靠、易扩展、高可用及丰富的功能特性收到越来越多企业的青睐。【实例】SpringBoot整合RabbitMQ实现消息的发送与接收。实例要求:实现SpringBoot整合RabbitMQ框架。 实现RabbitMQ消息确认机制(ACK)。 实现RabbitMQ消息队列延迟功能。原创 2021-02-02 17:30:49 · 6627 阅读 · 7 评论 -
SpringBoot整合Redis并实现Redis工具类
Redis 是用 C 语言开发的一款开源的、高性能的键值对存储数据库。它采用 BSD 协议,为了适应不同场景下的存储需求,提供了多种键值对类型,到目前为止 Redis 数据库支持5种数据类型,分别是String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Sorted Set(有序集合)。Redis 是目前使用最广泛的内存数据存储系统之一。它支持更丰富的数据结构,支持数据持久化、事务、HA(高可用 High Available)、双机集群系统、主从库。Redis是一款功能强大的数据库,原创 2020-12-22 17:37:20 · 1496 阅读 · 0 评论 -
SpringBoot整合Quartz实现定时任务
1、Quartz简介Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。1.1 Quartz的三大核心组件调度器:Scheduler。 任务:JobDetail。 触发器:Trigger,包括 SimpleTrigger 和 CronTrigger。(1)Jo原创 2020-11-08 11:48:22 · 32192 阅读 · 4 评论 -
SpringBoot使用@Scheduled注解实现定时任务
序言Spring 3.0 版本之后自带定时任务,提供了@EnableScheduling注解和@Scheduled注解来实现定时任务功能。使用SpringBoot创建定时任务非常简单,目前主要有以下三种创建方式:1、基于注解(@Scheduled) 2、基于接口(SchedulingConfigurer) 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库中读取指定时间来动态执行定时任务,这时候基于接口的定时任务就派上用场了。 3、基于注解设定多线程定时任务1、基于注解(@Schedu原创 2020-10-31 16:29:21 · 125690 阅读 · 9 评论 -
SpringBoot获取YAML配置文件中的属性值(一):使用@Value注解、@ConfigurationProperties注解
SpringBoot支持使用Properties和YAML两种配置方式。两者功能类似,都能完成SpringBoot的配置,但是Properties的优先级要高于YAML(YAML语言的文件以“.yml”为后缀)。使用application.yml文件配置SpringBoot项目。主要对SpringBoot项目的端口号、超时时间、参数值等进行配置。YAML文件的好处是——它采用的是树形结构,一目了然。如下:原创 2020-10-23 16:26:39 · 22192 阅读 · 0 评论 -
SpringBoot使用RedisTemplate操作Redis的5种数据类型
Spring 封装了RedisTemplate 来操作 Redis,它支持所有的 Redis 原生的 API。在RedisTemplate 中定义了对5种数据结构的操作方法。opsForValue():操作字符串。 opsForHash():操作散列。 opsForList():操作列表。 opsForSet():操作集合。 opsForZSet():操作有序集合。下面通过实例来理解和应用这些方法。这里需要特别注意的是,运行上述方法后要对数据进行清空操作,否则多次运行会导致数据重复操作。..原创 2020-09-30 18:50:27 · 17015 阅读 · 6 评论 -
SpringBoot整合Redis实现数据缓存
1、认识Spring CacheSpring Cache是Spring提供的一整套缓存解决方案。它本身并不提供缓存实现,而是提供统一的接口和代码规范、配置、注解等,以便整合各种Cache方案,使用户不用关心Cache的细节。Spring支持“透明”地向应用程序添加缓存,将缓存应用于方法,在方法执行前检查缓存中是否有可用的数据。这样可以减少方法执行的次数,同时提高响应的速度。缓存的应用方式“透明”,不会对调用者造成任何干扰。只要通过注解@EnableCaching启用了缓存支持,Spring Boo.原创 2020-09-26 17:26:15 · 1444 阅读 · 1 评论 -
SpringBoot整合Druid实现数据库连接池和监控
1、Druid的简介Druid是Java语言中使用的比较多的数据库连接池。Druid还提供了强大的监控和扩展功能。下面将介绍SpringBoot整合Druid实现数据库连接池和监控功能。官方文档:《Druid官方文档》2、创建SpringBoot项目与数据表【实例】SpringBoot整合Druid实现数据库连接池和监控,使用MyBaits操作数据库,获取用户信息,如下图:2.1 创建项目(1)创建SpringBoot项目,项目结构如下图:(2)使用Maven添.原创 2020-09-22 17:10:35 · 5181 阅读 · 1 评论 -
SpringBoot与MyBatis的整合与综合实例
SpringBoot是Spring框架的扩展,其设计目的是用来简化Spring应用的初始搭建以及开发过程,使得开发变得更快、更高效、更自动化。MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程、以及高级映射。MyBatis3提供的注解可以取代XML。例如,使用注解@Select直接编写SQL完成数据查询。下面将介绍SpringBoot与MyBatis的整合。1、创建数据表在MySQL数据库中创建用户信息表(tb_user),并添加数据。-- 判断数据表是否存在,存在则删除原创 2020-06-12 17:28:43 · 1235 阅读 · 0 评论 -
SpringBoot整合Shiro框架实现加密、登录、授权
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。下面将使用SpringBoot整合Shiro框架实现加密、登录、授权。1、创建数据表使用MySQL数据库,创建实例所需的数据表,用户信息表、角色信息表、权限信息表等。1.1 数据表结构1.2 数据表脚本(1)创建数据表脚本。-- 创建数据表:us.原创 2020-05-30 11:50:58 · 7722 阅读 · 7 评论 -
SpringBoot使用MockMvc对Controller层进行单元测试
MockMvc 是 Spring 框架中用于测试 Spring MVC 控制器的一个重要工具。它提供了一个强大的 API,使得开发者能够模拟 HTTP 请求并验证响应,而无需实际启动服务器。Mockito 是 GitHub 上使用最广泛的 Mocking 框架。它提供简洁的 API 来测试。Mockito 简单易学、可读性强、验证语法简洁。在单元测试中,虽然对于一些功能可以通过模拟 Servlet 内置对象予以实现,但是对于一些特殊的功能必须通过访问指定 URL 地址才能予以实现。原创 2020-05-28 15:57:29 · 4462 阅读 · 2 评论 -
SpringBoot使用JUnit5实现单元测试
单元测试(Unit Test)是为了检验程序的正确性。一个单元可能是单个程序、类、对象、方法等,它是应用程序的最小可测试部件。SpringBoot提供了 spring-boot-starter-test 启动器。通过它,能引入一些有用的测试库。在SpringBoot中进行单元测试很简单,它已经自动添加好了Test的Starter依赖。JUnit5是对程序代码进行单元测试的Java框架。它用来编写自动化测试工具,降低测试的难度、减少烦琐性、并有效避免出现程序错误。原创 2020-05-28 15:28:29 · 4522 阅读 · 0 评论 -
SpringBoot使用ApplicationContext对象获取Bean
ApplicationContext对象是Spring容器的上下文对象。下面将介绍基于SpringBoot平台完成ApplicationContext对象的获取,并通过实例获取Spring管理的Bean。(1)创建User(用户信息实体类),并在类上添加@Component注解。import org.springframework.stereotype.Component;/** * 用户信息实体类 * @author pan_junbiao **/@Componentpublic原创 2020-05-27 15:39:42 · 5988 阅读 · 1 评论 -
SpringBoot整合Swagger实现接口文档
在项目开发中,一般都是前后端分离开发的,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发、维护。为了便于编写和维护稳定,可以使用Swagger来编写API接口文档,以提升团队的沟通效率。【示例】SpringBoot整合Swagger实现接口文档。1、配置Swagger(1)添加Swagger依赖。在pop.xml文件中加入Swagger2的依赖,配置如下:<!--Swagger依赖--><dependency> &l原创 2020-05-27 11:30:32 · 1535 阅读 · 0 评论