自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

江南烟雨却痴缠丶

微信公众号:柳成荫同学

  • 博客(118)
  • 资源 (3)
  • 收藏
  • 关注

原创 关于ThreadLocal的那点事

ThreadLocal是什么ThreadLocal类提供线程内部的局部变量,在多线程环境(即多线程并发场景)访问时能够保证变量相对独立于其他线程内的变量(即线程隔离),用于关联线程和线程上下文(意味着可以通过ThreadLocal在同一线程下,不同的组件里传递共用变量)。@Datapublic class ThreadDemo2 { private ThreadLocal<String> tl = new ThreadLocal<>(); public sta

2021-12-19 20:56:28 1464

原创 SpringBoot - OAuth2第三方登录之QQ登录

之前写过一篇OAuth2 - 第三方登录之新浪登录,提到过QQ审核很复杂,我之前提交审核很多次,各种原因失败,这一次总算成功了,所以便来记录一下其中过程。QQ登录需要做哪些准备?1、服务器+备案过的域名。2、一个能跑起来的服务,且登录页面正常,有QQ登录的跳转按钮。可以通过ICP备案这个网站去查询你的备案信息。红框标出来的,就是下面创建应用要使用的。QQ互联 - 创建应用进入到QQ互联官网,登录之后需要先进行一把开发者身份认证(需要手持身份证)。开发者身份审核通过之后,就可以去应用管理里创建

2021-12-18 00:15:12 2142

原创 职责链模式 - 一个有顺序且有等级的模式

在生活中,一件事情需要经过多个对象处理是比较常见的场景。比如,请假流程。假设有这样一个设定:直属领导可批准2天以内的假期,二级领导可以批准4天以内的假期,一级领导可以批准7天以内的假期(最多只可7天)。那么员工必须根据请假的天数找不同的领导申请,这样是比较麻烦的,员工需要记住具体的领导的相关信息。那么有没有这样一种方式:员工只需要提交请假申请到自己的直属领导,无需关心其他领导的信息,就能得到处理?那么答案就是:职责链模式(责任链模式)。1、定义为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求

2021-08-03 10:26:27 606 1

原创 Apollo - 阿波罗配置中心使用,一文搞定!

Apollo基本概念一、简介Apollo - A reliable configuration management systemApollo的Github地址Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用的不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。Apollo包括服务端和客户端两部分:1、服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安

2021-07-30 17:52:55 17443

原创 MacOS - JDK和Maven安装与环境配置

公司发的电脑是MBP,由于从来没有用过Mac,所以配置环境都觉着很难受,遂将其记录下来。1、JDK安装与环境配置JDK下载地址①安装下载好了正常安装即可。打开终端,输入java -version即可查看版本,输入java可以查看详细信息。此时,jdk安装完毕,但是未配置环境变量。JDK的实际位置:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home②环境变量配置1、打开终端,查看文件ls -a如果没有.ba

2021-07-05 17:32:24 881

原创 SpringBoot - Spring事件监听机制的简单使用

什么是Spring事件监听机制Spring的ApplicaitonContext可以发布事件和注册相应的事件监听器。事件监听和发布的三个概念1、事件源:事件的生产者,任何一个event都有一个事件源。2、事件发布器:它是事件和事件监听器的一个桥梁,负责把事件通知到事件监听器。3、事件监听器注册表:用于存储事件监听器。事件类(ApplicationEvent)ApplicationEvent继承自EventObject,其包含一个构造函数ApplicationEvent(Object sourc

2021-06-20 14:50:05 494

原创 SpringBoot - SpringSecurity结合JWT的身份验证及动态权限解决方案

花了点时间写了一个SpringSecurity集合JWT完成身份验证的Demo,并按照自己的想法完成了动态权限问题。在写这个Demo之初,使用的是SpringSecurity自带的注解权限,但是这样权限就显得不太灵活,在实现之后,感觉也挺复杂的,欢迎大家给出建议。Demo下载地址,见文末。JWT是什么可以参考我另一篇博文:浅谈JWT身份认证及其优缺点认证流程及授权流程我画了个建议的认证授权流程图,后面会结合代码进行解释整个流程。一、登录认证阶段实现SpringSecurity的UsernameP

2021-03-28 03:01:01 2149

原创 浅谈JWT身份认证及其优缺点

一、登录模式在介绍JWT之前,我要先介绍一下常见的几种登录模式。1、单一服务器模式(Session)我们登录认证成功之后,将用户信息就存放在服务端(Session),然后将其对应的session_id存储在客户端(Cookie),从Cookie中取出session_id,服务端就可以根据这个session_id获取对应的Session,从而获取存储用户信息。其优点是:Session自动续期,用户体验较好其缺点是:①没有分布式架构,无法支持横向扩展。即分布式架构的情况下,其他服务器是没有办法获取到

2021-03-27 18:50:56 5314 3

原创 logback - 自定义日志脱敏组件,一种不错的脱敏方案

前言在我们书写代码的时候,会书写许多日志代码,但是有些敏感数据是需要进行安全脱敏处理的。对于日志脱敏的方式有很多,常见的有①使用conversionRule标签,继承MessageConverter②书写一个脱敏工具类,在打印日志的时候对特定特字段进行脱敏返回。两种方式各有优缺点:第一种方式需要修改代码,不符合开闭原则。第二种方式,需要在日志方法的参数进行脱敏,对原生日志有入侵行为。自定义脱敏组件(slf4j+logback)一个项目在书写了很多打印日志的代码,但是后面有了脱敏需求,如果我们去

2021-01-29 20:20:09 11690 6

原创 slf4j+logback - logback.xml配置文件解析

前言以前写代码,不注重书写log日志,都是通过system.out.println来当做日志使用。后来看了别人的代码,才知道日志的重要性。一般来说,在调用其他地方接口之前一定要打印日志,将传参打印一下,便于排查问题。即使我们不配置logback.xml,其实控制台依然会输出日志(有默认的输出方案)。我们可以通过logback.xml做一些个性化的日志输出,也可以定义一些输出到文件的日志输出方式等等。写这个博客,主要是方便以后需要用到logback能一下找到。在此之前,搜到很多一模一样的关于logbac

2021-01-09 00:07:17 1521 1

原创 SpringBoot - AOP+自定义注解实现一个日志插件

1、引入相关依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency><dependency> <groupId>org.projectlombok</groupId> <art

2020-12-29 00:57:52 695

原创 synchronized - 八锁问题及扩展

通过8锁问题,可以大致清楚synchronized是锁的什么东西。通过对8锁问题的扩展,可以进一步理解synchronized。8锁问题1、一个对象,两个synchronized方法,一个方法睡眠public class LockTest { public static void main(String[] args) { Phone phone = new Phone(); // 一个Phone对象 new Thread(() -> {

2020-11-24 22:50:19 878 4

原创 模板方法模式 - 父类定义步骤的模式

现实生活中很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是点单->吃东西->买单。但是第二步吃东西里,到底是先吃汉堡还是先吃鸡肉卷,这个步骤是可变的。定义定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得一个子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。结构AbstractClass(抽象类)在抽象类中定义一系列基本操作,这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对

2020-10-26 20:29:30 311

原创 策略模式 - 合适的方案才是最好的方案

在很多情况下,实现某个目标的途径不止一条,例如在外出旅游时游客可以选择多种不同的出行方式,如骑自行车、坐汽车、坐火车、坐飞机,根据实际情况选择最合适的一种出行方式。定义定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法可以独立于使用它的客户而变化。结构Context(环境类)环境类是使用算法的角色,它在解决某个问题时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。Strategy(抽象策略类)抽象策略类为所支持的算法声明抽象方法,是所有

2020-10-26 19:52:24 258

原创 装饰模式 - 给已有的功能增加额外的职责

对新房进行装修并没有改变房屋用于居住的本质,但它可以让房子变得更漂亮,更能满足居家需求。装饰模式可以在不改变一个对象本身的基础上给对象增加额外的新行为,在现实生活中到处存在这种情况。定义动态的给一个对象增加一些额外的职责。就扩展而言,装饰模式提供了一种比使用子类更加灵活的替代方案。结构Component(抽象构件)它是具体构件和抽象装饰类的共同父类,声明了在具体的构件中实...

2020-10-26 19:07:55 274

原创 抽象工厂模式 - 产品等级与产品族的纠缠

工厂方法模式中的每个具体工厂只有一个或者一组重载的工厂方法,只能生产一种产品,可能会导致系统中存在大量的工厂类,会增加系统的开销。有时候需要工厂可以提供多种产品对象,而不是单一的产品对象。例如一个电器工厂,它可以生产电视、电冰箱、洗衣机、空调之类的。这时候就可以将一些相关产品组成一个产品族,由一个工厂来统一生产。产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类包括海尔电视机...

2020-10-26 11:17:56 505

原创 工厂方法模式 - 抽象工厂与抽象产品的结合

工厂方法模式是在简单工厂模式上再加了一层,添加了一个抽象工厂和具体工厂。即不再使用一个工厂类来统一负责所有产品的创建,而是把创建具体产品的任务交给了专门的工厂子类去完成。比如说,我要生产矩形、圆形、菱形这三种形状,就不再使用一个工厂了,而是让矩形工厂、圆形工厂、菱形工厂去完成,而这三个工厂又是形状工厂(抽象工厂)的子工厂。如果我们想要新生产一个椭圆形,只需要新增一个椭圆形工厂就行,让椭圆形工厂去完...

2020-10-26 11:14:58 305

原创 简单工厂模式 - 工厂模式基础之魂

简单工厂模式并不属于GoF的23种经典模式,但它通常作为其他工厂模式的基础。定义定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。结构Factory(工厂角色)即工厂类,它是简单工厂模式的核心。负责创建所有产品实例的内部逻辑,它可以直接被外界直接调用,用来创建所需要的产品对象。该类内部提供一个静态方法factoryMethod(),用...

2020-10-26 10:48:20 141

原创 算法 - Java实现二分、插值、斐波那契查找法

一、二分查找法二分查找法,就是对一个有序数组进行拆分。找到这个数组的中间的那个数的值,将查找的这个数与其比较。这里是从小到大排序的,如果比这个中间值小,就在把中间值左边看成一个数组,在这个数组里继续二分查找,直到查到(或者查完全部也没查到).如果比这个中间值大,就在把中间值右边看成一个数组,在这个数组里继续二分查找,直到查到(或者查完全部也没查到).代码实现public class BinarySearchDemo { public static void main(String[] ar

2020-07-29 23:48:38 291

原创 算法 - Java实现八大内排序算法(图解)

排序分类1、内部排序指将需要处理的所有数据都加载到内部存储器中进行排序。2、外部排序数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。一、冒泡排序冒泡排序也属于内部排序法,属于交换排序。基本思想通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒。因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断

2020-07-29 19:35:56 1340

原创 Nacos - 支持MySQL8并切换为MySQL存储

在1.3.1版本之前,Nacos不支持MySQL8。今天想在Linux上做一下集群(之前图方便,都是在Windows上操作的),想起这个问题,所以就在博客上记录一下。在此之前的版本,要想支持MySQL8.0,需要自己下载源码进行修改,然后编译。我这里以1.1.4版本为例。支持MySQL81、下载源码 - Nacos下载地址2、导入到Idea中(会下载很多依赖,可以直接根据步骤找到文件,使用记事本打开)3、修改pom文件,引入MySQL8.0的依赖4、修改MysqlHealthCheckPr

2020-07-15 17:29:52 880

原创 SpringBoot - 支付宝支付之沙箱环境简单使用

创建应用1、进入支付宝开放平台 支付宝开放平台2、完善信息3、接入应用支付宝使用的加密方式1、对称加密 - 不安全即加密和解密用同一种算法(钥匙),比如发送方给接受方要发送一串文字,但是不能让人知道,所以需要加密,将加密后的字符串通过网络传输,给到接收方,接收方收到秘闻,用同一种算法获取明文。因此只要知道了这种算法(钥匙),在网络传输中截取到,就可以随意解密,这种方式不安全。2、非对称加密即加密时用算法A(秘钥A),解密的时候用算法B(秘钥B),即使在网络传输截取到密文,由于不知道秘

2020-07-10 14:41:17 3416 2

原创 接口调用幂等性问题及解决方案

什么是接口调用幂等性问题?现如今我们的系统大多拆分为分布式架构、微服务架构,一套系统中包含了多个子系统服务,而一个子系统服务往往会去调用另一个服务,而服务调用服务无非就是使用RPC通信或者RESTFUL,既然是通信,那么就有可能在服务器处理完毕后返回结果的时候挂掉,这个时候用户端发现很久没有反应,那么就会多次点击按钮,这样请求有多次,那么处理数据的结果是否要统一呢?那是肯定的!接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的, 不会因为多次点击而产生了副作用:比如说支付场景,用户购

2020-07-02 22:13:27 2437

原创 SSO - 使用cookie和session实现单点登录

什么是单点登录单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是目前比较流行的。cookie+session实现单点登录之前的文章有记录过使用CAS开源项目来实现单点登录,也有通过JWT来实现

2020-06-22 01:19:45 3543 1

原创 SpringSession - 分布式Session解决方案及SpringSession基本使用

分布式Session的几种解决方案1、Session复制Tomcat服务器互相同步session。优点:web-server (Tomcat) 原生支持,只需要修改配置文件缺点:1、session同步需要数据传输,占用大量网络带宽,降低了服务器群的业务处理能力2、任意一台web-server保存的数据都是所有web-server的sesdion总和,受到内存限制无法水平扩展更多的web-server3、大型分布式集群情况下,由于所有web-server都全量保存数据,所以此方案不可取。2

2020-06-20 20:39:49 1436

原创 SpringBoot - OAuth2第三方登录之新浪微博登录

之前写过一篇OAuth2 - 第三方登录之微信登录,但是微信的开放平台的资质需要有公司/企业才能注册。如果是个人的话,可以使用其他个人开发者就可以使用的。比如QQ、新浪微博。QQ的话,需要审核之后才能使用,需要手持身份证照。而微博的话,在开发期间使用无需审核就可以使用。微博开放平台 - 创建应用微博 - 开放平台地址1、登录之后选择网站接入2、完善个人开发者信息3、创建应用创建自己要使用微博登录功能的应用。4、设置回调地址即登录授权成功之后的回调地址5、添加测试用户测试用户即微

2020-06-19 23:31:43 2055 4

原创 REST - RESTFUL风格是什么以及Java中怎么使用

什么是 RESTFUL 风格?REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,指的是一组架构约束条件和原则,满足这些约束条件和原则的应用程序或设计就是 RESTful。REST并没有一个明确的标准,而更像是一种设计的风格。Representational(表述性) : REST 资源实际上可以用各种形式来进行表述,包括 XML、JSON 甚至 HTML——最适合资源使用者的任意形式。State(状态):当使用 REST 的时候

2020-06-09 01:21:57 1185

原创 JDK - CentOS7下安装JDK8

JDK1.8下载地址:JDK1.8下载地址,选择tar.gz包1、将tar.gz包上传我这里上传到/usr/local,版本为1.8.0_2212、解压cd /usr/java/tar -zxvf jdk-8u221-linux-x64.tar.gz3、配置环境变量修改profile文件vi /etc/profile在文件末尾添加如下配置:JAVA_HOME=/usr/java/jdk1.8.0_221CLASSPATH=$JAVA_HOME/lib/PATH=$PATH:$JA

2020-06-05 21:47:34 110

原创 MySQL - Linux安装和卸载MySQL8、配置远程连接授权

本文是在Cent OS7下通过yum源来进行安装MySQL8.0,下载地址:MySQL源安装包安装1、通过wget命令下载本文在/home目录下进行,一般也可以在/local/usr/下进行。wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm2、yum安装MySQL源yum localinstall mysql80-community-release-el7-1.noarch.rpm检查是否安装

2020-06-05 21:36:26 359 1

原创 Redis - 实现分布式锁的阶段演进

①演进阶段一获得锁就执行业务逻辑,没有获得锁就继续调用这个方法形成一个自旋,就类似于synchronized。伪代码:public void getData(){ boolean lock = redisTemplate.opsForValue.setUfAbsent("lock","1111"); if(lock){ // 执行业务.. // 删除锁 redisTemplate.delete("lock");

2020-05-29 15:27:25 295

原创 Spring - JSR303数据校验

在做项目的时候需要对表单的值进行校验,只有校验通过才能提交,一般来说前端和后端都需要做校验,JSR303是做后端校验的一种方式。JSR303简介JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务,JSR已成为Java界的一个重要标准。JSR-303是JAVA EE 6 中的一项子规范,叫做Bean V

2020-05-14 16:00:12 504

原创 NVM - node.js版本管理工具的安装及基本使用

简介nvm全名node.js version management,是一个nodejs的版本管理工具,通过它可以安装和切换不同版本的nodejs,解决了新老项目维护时切换node的问题。下载及配置GitHub:nvm-windows注意事项:不要把nvm安装在中文路径或是文件夹带有空格的路径下,这会导致nvm部分命令失效。配置淘宝镜像nvm默认的下载地址http://nodejs.org/dist/是国外服务器,速度非常慢,因而可以切换到淘宝的镜像,下载速度会快很多(尤其体现在下载npm的时候

2020-05-09 19:22:34 375

原创 Excel - POI与EasyExcel操作Excel表

POIApache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。结构:HSSF - 提供读写Microsoft Excel格式档案的功能。XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。HWPF - 提供读写Microsoft Word格式档案的功能。HSLF -...

2020-05-05 16:40:05 481

原创 Redis - Redis集群及主从复制、哨兵模式

Redis主从复制主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave 以读为主。默认情况下,每台Redis服务器都是主节点。且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点...

2020-05-05 01:27:53 1232

原创 Redis - 消息发布订阅机制

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。发布者生产消息放到队列里,多个监听队列的消费者都会收到同一份消息。Redis客户端可以订阅任意数量的频道。订阅/发布消息图下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:当有新消息通过...

2020-05-04 13:30:31 974

原创 Redis - 事务与乐观锁

事务Redis的事务与MySQL的事务差别较大。Redis的事务本质是一组命令的集合。也就是说一个事务中的所有命令都会被序列化,在事务执行的时候,会按照顺序执行这些命令。即Redis具有:一次性、顺序性、排他性(不受其他命令干扰)。在Redis中,事务没有隔离级别的概念。Redis事务流程1、开启事务(multi)2、命令入队(即依次输入命令)3、执行事务(exec)所有命令都是...

2020-05-03 17:59:04 161

原创 SpringBoot - 整合Swagger2

简介前后端分离开发模式中,api文档是最好的沟通方式。Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的 Web 服务。1、及时性 (接口变更后,能够及时准确地通知相关前后端开发人员)2、规范性 (并且保证接口的规范性,如接口的地址,请求方式,参数及响应格式和错误信息)3、一致性 (接口信息一致,不会出现因开发人员拿到的文档版本不一致,而出现分歧)4...

2020-05-01 14:30:48 261

原创 JDK8新特性 - 接口默认方法与静态方法、重复注解与类型注解

Java 8中允许接口中包含具有具体实现的方法,该方法称为默认方法,默认方法使用 default关键字修饰。接口默认方法与静态方法接口中的默认方法其实在一定程度上是违背了接口原本存在的意义。一、默认方法1、仅实现接口// 接口public interface MyInterface { // 默认方法 default String getName() { return "MyI...

2020-04-29 22:46:09 261

原创 JDK8新特性 - 新时间日期API

LocalDate、LocalTime、LocalDateTimeLocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法基本使用@Te...

2020-04-29 20:03:54 196

原创 JDK8新特性 - Stream API及Optional类

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。Stream是什么它是数据渠道,用于操作数据源(集...

2020-04-29 16:07:29 717

activeMQ安装包.zip

里面包含apache-activemq-5.12.0-bin.tar.gz,即Linux下的ActiveMQ的安装包。

2020-01-30

Redis安装压缩包

包含Redis-x64-3.2.100.zip、redis-4.0.9.tar.gz这两个压缩包,zip是Windows下的,tar.gz是Linux下的。

2020-01-29

Solr相关压缩包.zip

包含Tomcat8在Linux环境下的压缩包apache-tomcat-8.5.32.tar.gz、中文分词器IKAnalyzer.zip、Solr安装包solr-4.10.3.tar、solrJ.rar四个文件。

2020-01-28

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除