SpringBoot + SpringCloud + SpringSecurity学习过程中的源码汇总,沉淀记录下学习历程
说明:Spring系列教程现已根据专栏方式进行收集整理,更便于系统学习,详情查看: 一灰灰的Spring系列专栏
欢迎关注公众号 一灰灰blog
更多干货持续分享
如果想在本机使用这个项目的demo,下面有一些注意事项
环境要求
java: jdk1.8
maven: 3.2+
spring boot: 2.2.1.RELEASE
ide: IDEA/Eclipse/NetBeans随意
## 不同项目的环境依赖,请以项目对应的博文要求为准
db: mongodb + mysql + redis + solr + elasticsearch
中间件: promotheus + grafana + kibana + rabbitmq
IDEA插件
# 必须
lombok
# 推荐
maven helper: 查看依赖树的好工具(排除依赖冲突非常棒)
Free MyBatis plugin: mybatis的mapper与xml跳转比较方便
Mybatis log Plugin:日志
CodeGlance: 类似sublimetext 右边的快速预览框
Rainbow Brackets: 不同层级的括号颜色不一样
所有博文集中发布在个人博客网站 : 一灰灰Blog-Spring
大致规划的内容包括以下章节,希望能用半年到一年(严重超期)的时间完成....
I. 基础篇
- db读写
- 基本配置,数据源,多数据源
- jdbcTemplate
- jpa
- 项目工程: spring-boot/102-jpa
- mybatis
- mybatis plus
- Jooq
- influxdb 时序数据库 - 项目工程: spring-boot/130-influxdb , spring-boot/131-influxdb-java
- Mongo
- 项目工程
- 基础环境 spring-boot/110-mongo-basic
- mongoTemplate使用姿势 spring-boot/111-mongo-template
- 项目工程
- Redis读写
- 项目工程:
- 基本环境构建 spring-boot/120-redis-config
- jedis环境构建 spring-boot/121-redis-jedis-config
- redisTemplate使用姿势 spring-boot/122-redis-template
- lettuce环境构建 spring-boot/123-redis-lettuce-config
- redis集群实例工程 spring-boot/124-redis-cluster
- 排行榜应用实例工程 spring-case/120-redis-ranklist
- 站点统计应用实例工程 spring-case/124-redis-sitecount
- 项目工程:
- MemCache
- InfluxDb
- SpringCache
- 定时器
- 搜索 ES
- 搜索 Solr
- 过滤器
- 项目工程:
- 基本使用姿势:spring-boot/210-web-filter
- filter优先级: spring-boot/210-web-filter-order
- 项目工程:
- 拦截器
- 项目工程:spring-boot/213-web-interceptor
- 基本使用姿势: 拦截器
- Get/Post/Put/Delete等http方法支持
- 参数绑定(get/post参数解析,自定义参数解析器)
- 返回相关
- 异常处理
- 安全相关(SQL/XSS等注入)
- 跨域处理
- WebSocket
- reactive
- 注册中心
- 配置中心
- 网关路由
- 负载均衡
- 熔断器
- 链路监控
- 安全模块
- oauth
- admin
- xxx
项目说明
项目 | 说明 | 知识点 |
---|---|---|
SpringBoot | SpringBoot项目 | - |
000-properties | 【配置】使用姿势 | @PropertySource 指定配置文件,@ConfigurationProperties 指定配置前缀, @value 配置绑定 |
001-properties | 【配置】环境选择 | 配置spring.profiles.active 指定环境 |
002-properties | 【配置】刷新示例 | SpringCloud生态配置刷新@RefreshScope ,EnvironmentChangeEvent 配置变更事件 |
002-properties-bind | 【配置】刷新绑定的各种知识点 | @ConfigurationProperties |
002-dynamic-envronment | 【配置】自定义配置源 | MapPropertySource |
002-properties-value | 【配置】@Value扩展知识点 | @Value |
003-log | 【日志】集成logback | logback日志集成与配置 |
003-log4j2 | 【日志】集成log4j2 | log4j2日志集成与配置 |
004-bean | 【bean】使用姿势 | bean三种定义姿势 bean三种注入方式 |
005-autoconfig | 【bean】自动加载 | @Configuration 自动加载配置类 |
005-config-selector | 【bean】选择注入 | ImportSelector 选择在接口的多个实现中,具体实例化哪个 |
006-dynamicbean | 【bean】动态注册bean | BeanDefinitionRegistryPostProcessor 扩展实现bean动态注册 |
007-conditionbean | 【bean】条件注入 | @Coinditional 使用姿势 |
008-beanorder 008-beanorder-addition 008-beanorder-addition2 |
【bean】加载顺序 | bean加载顺序的反面示例与正确写法 |
009-schedule | 【定时器】定时任务/计划任务 | @Scheduled 基本语法与自定义线程池 |
010-aop | 【AOP】切面 | aop基本使用姿势与注意事项 |
011-aop-logaspect | 【AOP】切面 | 实战,日志切面 |
012-context-listener | 【Listener】事件 | ContextListener |
013-spel | 【SpEL】 | SpEL语法与实例 |
014-spel-aop | 【SpEL】 | SpEL & aop整合时注意事项 |
100-h2database | 【DB】h2database整合 | - |
100-mysql | 【DB】mysql整合 | - |
101-jdbctemplate | 【DB】jdbctemplate使用姿势 CURD详解 | JdbcTemplate |
101-jdbctemplate-transaction | 【DB】事务 | @Transactional 声明式; 编程式事务 - 隔离级别 传递属性 |
102-jpa | 【DB】 jpa使用姿势 | JPA |
102-jpa-errorcase | 【DB】环境配置易错点 | @EnableJpaRepositories , @EntityScan 指定扫描包 |
102-jpa-errorcase2 | 【DB】Entity映射错误 | Field映射POJO |
103-mybatis-xml | 【DB】mybatis xml配置整合方式 | mybatis |
104-mybatis-noxml | 【DB】mybatis 注解整合方式 | mybatis |
105-mybatis-plus | 【DB】mybatis-plus整合 | mybatis-plus |
106-mybatis-plus-generator | 【DB】mybatis-plus代码自动生成 | mybatis-plus |
107-jooq-aop | 【DB】jooq体验demo,jooq+aop导致项目启动巨慢的坑 | jooq |
108-jooq-curd | 【DB】jooq CURD使用姿势 | jooq |
108-jooq-mysql | 【DB】jooq代码自动生成 | jooq-code-gen |
109-multi-datasource | 【DB】多数据源配置 | JdbcTemplate, DataSource |
109-multi-datasource-mybatis | 【DB】mybatis多数据源配置 | Mybatis DataSource |
109-multi-datasource-mybatis-ano | 【DB】mybatis多数据源配置 | Mybatis DataSource |
109-multi-datasource-mybatis-plus | 【DB】mybatis-plus多数据源配置 | Mybatis-Plus DataSource |
110-mongo-basic | 【DB】mongodb整合 | mongodb |
111-mongo-template | 【DB】mongodb CURD使用姿势 | MongoTemplate |
120-redis-config | 【redis】环境配置与基本使用 | redis |
121-redis-jedis-config | 【redis】jedis配置 | jedis |
122-redis-template | 【redis】RedisTemplate 使用姿势详解 | RedisTemplate |
123-redis-lettuce-config | 【redis】lettuce配置 | lettuce |
124-redis-cluster | 【redis】集群使用姿势 | redis集群实例 |
125-cache-ano | 【Cache】缓存注解 | Spring缓存注解使用姿势 |
130-influxdb | 【DB】influxdb整合及CURD | 时序数据库 influxdb |
131-influxdb-java | 【DB】influxdb封装 | 封装更服务SpringBoot规范的InfluxTemplate ,待实现 |
140-search-solr | 【Solr】solr环境+CURD使用姿势 | SolrTemplate , SolrClient |
141-search-solr-auth | 【Solr】solr开启授权无法更新索引的四种解决方案 | 解决solr更新索引报错问题 |
142-search-es | 【ES】es实例使用demo | ES,权限验证,CURD,高级特性等 RestHighLevelClient |
150-i18n | 【i18n】国际化 | 国际化支持 |
200-webflux | 【web】WebFlux实例 | React |
201-web | 【web】basic http实例 | springmvc |
202-web-params | 【web】请求参数解析的各种姿势 | get参数解析 post参数解析 自定义参数解析 HandlerMethodArgumentResolver |
202-web-params-validate | 【web】请求参数校验 | 参数校验validation-api |
203-websocket | 【web】websocket实例 | WebSocketHandler , WebSocketConfigurer |
204-web-static-resources | 【web】静态资源访问实例 | WebMvcConfigure , spring.resources.static-locations |
204-web-static-resources-ui | 【web】webjar静态资源 | 第三方jar包提供纯静态资源 |
204-web-xml | 【web】xml传参与返回实例 | xml传参返回使用姿势 |
204-web-xml-json | 【web】自定义返回数据类型的几种方式 | 返回xml,返回json,请求头、返回头,内容协商ContentNegotiationConfigurer |
204-web-freemaker | 【web】freemaker引擎整合 | freemaker |
205-web-thymeleaf | 【web】thymeleaf引擎整合 | thymeleaf |
206-web-beetl | 【web】beetl引擎整合 | beetl |
207-web-response | 【web】http响应的各种姿势 | 基本数据返回 重定向 错误页面配置 定制http code |
208-web-mapping | 【web】自定义url映射规则 | RequestCondition |
209-web-error | 【web】全局异常处理 | ControllerAdvice , ExceptionHandler |
210-web-filter | 【web】filter使用姿势 | HttpFilter过滤器 |
210-web-filter-order | 【web】filter优先级使用姿势 | HttpFilter , @Order |
211-web-servlet | 【web】servlet使用姿势 | Servlet |
212-web-listener | 【web】listener知识点 | Listener |
219-web-asyn | 【web】异步请求 | AsyncContext方式 Callable WebAsyncTask DeferredResult |
220-web-sse | 【web】sse 服务器发送事件 | SseEmitter |
221-web-resttemplate | 【web】RestTemplate使用姿势 | RestTemplate |
222-web-client | 【web】WebClient使用姿势 | WebClient |
223-webflux-params | 【web】webflux参数解析实例demo | webflux |
230-web-resin | 【web】resion容器整合 | resin |
300-rabbitmq | 【web】rabbitmq整合 | rabbitmq |
301-rabbitmq-publish | 【web】rabbitmq发送消息 | RabbitTemplate 消息确认模式 事务模式 |
302-rabbitmq-consumer | 【web】rabbitmq消费消息姿势 | @RabbitListener |
400-docker-demo | 【docker】docker整合 | Dockerfile |
410-zookeeper-basic | 【中间件】zk使用姿势 | ZooKeeper |
411-zookeeper-distributelock | 【中间件】zk 分布式锁 | DistributeLock |
SpringCase | 实战/应用演练项目 | - |
000-spi-factorybean | 借助FactoryBean实现SPI效果 | FactoryBean |
002-dynamic-config 002-dynamic-config-demo |
自定义配置加载与刷新示例工程 | 借助InstantiationAwareBeanPostProcessorAdapter + Spring事件机制实现@Value @RefreshScope |
006-importbean | 将非spring项目导入Spring生态 自定义注入实例 |
ImportBeanDefinitionRegistrar |
008-bean-order 008-bean-order-client |
指定bean加载优先级,让中间件的核心bean优于业务bean被加载 | InstantiationAwareBeanPostProcessorAdapter , @Import |
009-distribute-scheduler-task | 分布式定时任务mock实例 | AOP实现定时任务选择; 重写ScheduledAnnotationBeanPostProcessor 扩展定时任务生成 |
010-auto-inject | 自定义注入实现 | BeanPostProcessor 与 代理类创建 |
120-redis-ranklist | redis实现排行榜 | zset |
124-redis-sitecount | redis实现站点统计 | redisTemplate |
125-redis-distribuet-lock | redis分布式锁 | redisTemplate |
126-redis-delay-list | redis实现的演示队列 | redisTemplate |
201-web-api-version | web版本控制 | RequestMappingHandlerMapping |
202-web-qrcode-login | web扫码登录实战 | SseEmitter |
203-web-rest-adapter | url匹配规则自定义,子类继承父类的参数注解 | RequestMappingHandlerMapping , HandlerMethodArgumentResolver |
204-web-request-proxy | 基于接口的REST访问支持 | ClassPathBeanDefinitionScanner , ImportBeanDefinitionRegistrar |
205-web-rest-enhanced | 单机应用最小成本扩展REST服务示例 | RequestMappingHandlerMapping |
421-prometheus-metric | AOP实现自定义的Prometheus埋点上报 | Prometheus |
430-mail-alarm | 基于日志的邮件报警 | javaMailSender |
SpringSecurity | 安全 | |
000-basic-demo | 整合实例 | |
001-authentication-mem-config | 内存认证 | |
001-authentication-mem-userdetail | 内存认证 | |
002-authentication-db | db认证 | |
010-accesscontrol-rbac | rbac 权限管理 | |
011-accesscontrol-acl | acl权限管理 | |
spring-cloud | 微服务 | |
config-server | 配置中心 | spring cloud config |
eurka-server | 注册中心 | spring cloud eurka |
eurka-service-consumer | 服务提供者 | spring cloud eurka |
eurka-service-provider | 服务消费者 | ribbon feign |
gateway | 网关 | spring cloud gateway 网关 |
- 【SpringBoot实战】Bean之注销与动态注册实现服务mock
- 【SpringBoot实战】FactoryBean及代理实现SPI机制的实例
- 【SpringBoot实战】借助Redis实现排行榜功能
- 【SpringBoot实战】借助Redis搭建一个简单站点统计服务
- 【SpringBoot实战】AOP实现日志功能
- 【SpringBoot实战】徒手撸一个扫码登录示例工程
- 【SpringBoot实战】mock一个简单的分布式定时任务
- 【SpringBoot实战】Redis实现分布式锁(应用篇)
- 【SpringBoot实战】借助redis来实现延时队列(应用篇)
基础系列博文包括 AOP, IoC(DI,Bean), 日志, 自动配置等
配置
- 【基础系列】SpringBoot基础篇配置信息之如何读取配置信息
- 【基础系列】SpringBoot基础篇配置信息之多环境配置信息
- 【基础系列】SpringBoot基础篇配置信息之自定义配置指定与配置内引用
- 【基础系列】SpringBoot配置信息之配置刷新
- 【基础系列】SpringBoot配置信息之默认配置
- 【基础系列】实现一个自定义配置加载器(应用篇)
- 【基础系列】SpringBoot配置篇之PropertySource加载Yaml配置文件实例演示
- 【基础系列】ConfigurationProperties配置绑定中那些你不知道的事情
- 【基础系列】SpringBoot @Value之字面量及SpEL知识点介绍篇
- 【基础系列】SpringBoot之自定义配置源的使用姿势
- 【基础系列】SpringBoot基础篇@Value中哪些你不知道的知识点
- 【基础系列】SpringBoot应用篇@Value注解支持配置自动刷新能力扩展
IoC(DI/bean)
- 【基础系列】Bean之基本定义与使用
- 【基础系列】Bean之自动加载
- 【基础系列】Bean之条件注入@Condition使用姿势
- 【基础系列】Bean之@ConditionalOnBean与@ConditionalOnClass
- 【基础系列】Bean之条件注入@ConditionalOnProperty
- 【基础系列】Bean之条件注入@ConditionalOnExpression
- 【基础系列】Bean之多实例选择
- 【配置系列】Bean加载顺序之错误使用姿势辟谣
- 【基础系列】指定Bean初始化顺序的若干姿势
- 【基础系列】自动配置选择生效
- 【基础系列】Bean之动态注册
- 【基础系列】Bean之注销与动态注册实现服务mock(应用篇)
- 【基础系列】FactoryBean及代理实现SPI机制的实例(应用篇)
- 【基础系列】从0到1实现一个自定义Bean注册器(应用篇)
- 【基础系列-实战】如何指定bean最先加载(应用篇)
AOP相关
- 【基础系列】AOP之基本使用姿势小结
- 【基础系列】AOP之高级使用技能
- 【基础系列】AOP之拦截优先级详解
- 【基础系列】AOP实现一个日志插件(应用篇)
- 【基础系列】接口上注解AOP拦截不到场景兼容
- 【基础系列】Spring之AOP结合SpEL实现日志输出的注意事项
日志
定时任务
SpEL
事件
国际化
我们将db区分为传统的关系型数据库如mysql,NoSql如redis、mongodb,时序数据库influxdb
h2database
MongoDB
redis
- 【DB系列】Redis之基本配置
- 【DB系列】Redis之Jedis配置
- 【DB系列】Redis之String数据结构的读写
- 【DB系列】Redis之List数据结构使用姿势
- 【DB系列】Redis之Hash数据结构使用姿势
- 【DB系列】Redis之Set数据结构使用姿势
- 【DB系列】Redis之ZSet数据结构使用姿势
- 【DB系列】Redis之管道Pipelined使用姿势
- 【DB系列】Redis高级特性之Bitmap使用姿势及应用场景介绍
- 【DB系列】Redis高级特性之发布订阅
- 【DB系列】Redis高级特性之HyperLoglog
- 【DB系列】Redis高级特性之GEO
- 【DB系列】Redis集群环境配置
- 【DB系列】借助Redis实现排行榜功能(应用篇)
- 【DB系列】借助Redis搭建一个简单站点统计服务(应用篇)
- 【DB系列】缓存注解@Cacheable @CacheEvit @CachePut使用姿势介绍
- 【DB系列】SpringBoot缓存注解@Cacheable之自定义key策略及缓存失效时间指定
- 【DB系列】借助redis来实现延时队列(应用篇)
mysql
分别介绍多种不同的操作姿势
JdbcTemplate
- 【DB系列】JdbcTemplate之数据插入使用姿势详解
- 【DB系列】JdbcTemplate之数据查询上篇
- 【DB系列】JdbcTemplate之数据查询下篇
- 【DB系列】JdbcTemplate之数据更新与删除
- 【DB系列】JdbcTemplate之多数据源配置与使用
jpa
- 【DB系列】JPA之基础环境搭建
- 【DB系列】JPA之新增记录使用姿势
- 【DB系列】JPA之update使用姿势
- 【DB系列】JPA之delete使用姿势详解
- 【DB系列】JPA之query使用姿势详解之基础篇
- 【DB系列】JPA之指定id保存
- 【DB系列】JPA 错误姿势之环境配置问题
- 【DB系列】JPA错误姿势之Entity映射
mybatis
- 【DB系列】Mybatis+xml整合篇
- 【DB系列】Mybatis+注解整合篇
- 【DB系列】MybatisPlus整合篇
- 【DB系列】Mybatis-Plus代码自动生成
- 【DB系列】Mybatis多数据源配置与使用
- 【DB系列】Mybatis基于AbstractRoutingDataSource与AOP实现多数据源切换
- 【DB系列】Mybatis-Plus多数据源配置
事务
采坑、填坑
jooq
- 【DB系列】Jooq初体验
- 【DB系列】Jooq代码自动生成
- 【DB系列】Jooq之新增记录使用姿势
- 【DB系列】Jooq之记录更新与删除
- 【DB系列】Jooq批量写入采坑记录
- 【DB系列】Jooq之记录查询基础篇
- 【DB系列】Jooq之聚合查询
- 【DB系列】Jooq之常用函数使用姿势
- 【DB系列】Jooq之多表联合查询
- 【DB系列】Jooq之事务
搜索主要会区分solr和es
solr
- 【搜索系列】Solr环境搭建与简单测试
- 【搜索系列】Solr之文档新增与修改使用姿势
- 【搜索系列】Solr文档删除
- 【搜索系列】Solr查询使用姿势小结
- 【搜索系列】Solr身份认证与授权更新异常解决方案
es
消息队列,如rabbitmq, rocketmq, activemq, kafaka
rabbitmq
- 【MQ系列】springboot + rabbitmq初体验
- 【MQ系列】RabbitMq核心知识点小结
- 【MQ系列】SprigBoot + RabbitMq发送消息基本使用姿势
- 【MQ系列】RabbitMq消息确认机制/事务的使用姿势
- 【MQ系列】RabbitListener消费基本使用姿势介绍
web系列的东西就比较多了,基本上日常开发中,你需要的都会有;你没用过的也会有
- 【WEB系列】Spring MVC之基于xml配置的web应用构建
- 【WEB系列】Spring MVC之基于java config无xml配置的web应用构建
- 【WEB系列】一个web demo应用构建全过程
- 【WEB系列】Spring MVC之Filter基本使用姿势
- 【WEB系列】过滤器Filter使用指南
- 【WEB系列】过滤器Filter使用指南扩展篇
- 【WEB系列】Servlet 注册的四种姿势
- 【WEB系列】Listener四种注册姿势
- 【WEB系列】拦截器Interceptor使用姿势介绍
- 【WEB系列】SpringBoot之拦截器注入Bean的几种姿势
- 【WEB系列】Get请求参数解析姿势汇总
- 【WEB系列】Post请求参数解析姿势汇总
- 【WEB系列】如何自定义参数解析器
- 【WEB系列】如何支持下划线驼峰互转的传参与返回
- 【WEB系列】从0到1实现自定义web参数映射器
- 【WEB系列】参数校验Validation
- 【WEB系列】自定义请求匹配条件RequestCondition
- 【WEB系列】静态资源配置与读取
- 【WEB系列】XML传参返回实战 | 一灰灰Blog
- 【WEB系列】定义接口返回类型的几种方式 | 一灰灰Blog
- 【WEB系列】Freemaker环境搭建
- 【WEB系列】Thymeleaf环境搭建
- 【WEB系列】Beetl环境搭建
- 【WEB系列】返回文本、网页、图片的操作姿势
- 【WEB系列】请求重定向
- 【WEB系列】全局异常处理
- 【WEB系列】自定义异常处理HandlerExceptionResolver
- 【WEB系列】开启GZIP数据压缩
- 【WEB系列】自定义返回Http Code的n种姿势
- 【WEB系列】异步请求知识点与使用姿势小结
- 【WEB系列】SSE服务器发送事件详解
- 【WEB系列】springboot + websocket初体验
- 【WEB系列】RestTemplate 4xx/5xx 异常信息捕获
- 【WEB系列】RestTemplate基础用法小结
- 【WEB系列】RestTemplate之自定义请求头
- 【WEB系列】RestTemplate之中文乱码问题fix
- 【WEB系列】RestTemplate之超时设置
- 【WEB系列】RestTemplate之代理访问
- 【WEB系列】RestTemplate之Basic Auth授权
- 【WEB系列】RestTemplate之非200状态码信息捕获
- 【WEB系列】RestTemplate之文件上传
- 【WEB系列】AsyncRestTemplate之异步非阻塞网络请求介绍篇
- 【WEB系列】404、500异常页面配置
- 【WEB系列】xml传参与返回使用姿势
- 【WEB系列】整合resin容器
采坑、填坑
- 【WEB系列】SpringBoot文件上传异常之提示The temporary upload location xxx is not valid(填坑篇)
- 【WEB系列】中文乱码问题解决(填坑篇)
- 【WEB系列】RestTemplate之urlencode参数解析异常全程分析(填坑篇)
- 【WEB系列】thymeleaf foreach踩坑记录
应用实战
WebFlux系列
由于WebFlux和SpringMVC在一些基础上差别较大,单独开一个系列教程版块
webclient异步网络请求
- 【WEB系列】WebClient之基础使用姿势
- 【WEB系列】WebClient之文件上传
- 【WEB系列】WebClient之请求头设置
- 【WEB系列】WebClient之Basic Auth授权
- 【WEB系列】WebClient之超时设置
- 【WEB系列】WebClient之retrieve与exchange的使用区别介绍
- 【WEB系列】WebClient之非200状态码信息捕获
- 【WEB系列】WebClient之策略设置
- 【WEB系列】WebClient之同步与异步
记录SpringSecurity相关的所有技术文章,分类汇总如下,持续更新中
简单抽象的说一下SpringSecurity它的定义
- 很🐂的认证和访问权限校验框架
那么具体能干嘛?
- 用户登录认证:用户名+密码登录,确定用户身份
- 用户访问鉴权(常见的ACL访问控制列表,RBAC角色访问控制):判定是否有权限访问某个资源
- 安全保护(CSRF跨站点攻击,Session Fixation会话固定攻击…)
相关博文
微服务系列
Eureka系列
踩坑、填坑
docker
zookeeper
prometheus
- 【中间件】Prometheus大盘配置实战 | 一灰灰Blog
- 【中间件】Prometheus基于AOP实现埋点采集上报 | 一灰灰Blog
- 【中间件】Prometheus自定义埋点上报
- 【中间件】SpringBoot整合Prometheus实现应用监控
邮件
拒绝单机,欢迎start或者加好友支持
尽信书则不如无书,以上内容,一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
- 微博地址: 小灰灰Blog
- QQ: 一灰灰/3302797840
- WeChat: 一灰/liuyueyi25
公众号&博客
打赏码