《JavaEE开发的颠覆者 SpringBoot实战》 阅读笔记


                                          第一部分

                                     点睛Spring 4.x


第1章  Spring 基础

1.1  Spring概述

1.1.1  Spring简史

第一阶段:xml配置

在Spring 1.x时代,是使用xml配置Bean,随着项目的扩大,在不同的xml配置文件配置Bean.

第二阶段:注解配置

在Spring 2.x时代,伴随着JDK1.5支持注解,Spring提供了声明Bean的注解(例如:@Component、@Service)。在应用的基本配置(例如数据库配置)使用xml,业务配置使用注解。

第三阶段:Java配置

从Spring 3.x到现在,Spring提供了java配置的能力,使用Java配置可以让你更加理解你配置的Bean。Spring 4.x和SpringBoot都推荐使用Java配置。

1.1.2  Spring概述

Spring框架是一个轻量级的企业级开发的一站式解决方案,所谓的解决方案就是可以基于Spring解决Java EE开发的所有问题。SPring框架提供了IoC容器、AOP、数据访问、web开发、消息、测试等相关技术。

Spring使用简单的POJO(Plain Old Java Object)进行企业级开发,每一个被Spring管理的Java对象都称为Bean;Spring提供了一个IoC容器来初始化对象,解决对象之间的依赖管理和对象的使用。

1.  Spring的模块

Spring是模块化的,意味着你可以使用你所需要的Spring模块。

2.  Spring的生态

Spring发展到现在,不仅仅是Spring框架本身的内容,Spring提供了大量的基于Spring的项目,可以更深入的降低我们的开发难度,提高开发效率。

目前Spring的生态主要有以下项目,我们可以根据需要选择使用相应的项目。

1.2  Spring项目快速搭建

目前主流的项目构建工具有:Ant、Maven、Gradle等,本文使用Maven作为项目构建工具。

1.2.1  Maven简介

Apache Maven是一个软件项目管理工具,基于项目对象模型(Project Object Model,POM)的概念。Maven可以来管理项目的依赖、编译、文档等信息。

使用Maven管理的项目,项目依赖的jar包将集中放在用户目录下的.m文件夹中。

1.2.2  Maven安装

1.  下载Maven

2.  配置Maven

3.  测试安装

1.2.3  Maven的pom.xml

Maven是基于项目对象模型的概念运作的,所以Maven的项目都有一个pom.xml用来管理项目的依赖以及项目的编译等功能。

在项目中,我们关注以下的元素:

1. dependencies元素

此元素包含多个项目依赖所需要使用的.

2. dependency元素

内部通过groupId、artifactId以及version确定唯一的依赖,也称这三个为坐标。

groupId:组织唯一标识

artifactId:项目唯一标识

version:项目版本

3.  变量定义

4.  编译插件

5.  Maven运行方式

Maven会根据dependency中的依赖去maven中心下载相关的依赖包到本地仓库。

如果不知道所需的jar包怎么添加依赖,推荐到http://mvnrepository.com网站检索。

若Maven中心仓库没有所需要的jar包,可以通过下面的Maven命令打到本地Maven仓库后即可使用。例如安装Oracle驱动到本地仓库:

1.2.4  Spring项目搭建

1.  基于Spring Tool Suit搭建

2.  基于IntelliJ IDEA搭建

3.  基于NetBeans搭建

1.3  Spring基础配置

Spring框架本身的四大原则:

Spring所有功能的设计和实现都是基于此四大原则的。

1.3.1  依赖注入

1.  点睛

依赖注入(DI)和控制反转(IoC)在Spring中是同等概念,控制反转是通过依赖注入实现的。

依赖注入:指的是容器负责创建对象和维护对象之间的依赖关系,而不是通过对象本省负责自己的创建和解决自己的依赖。

依赖注入的主要目的是为了解耦合,体现了组合的理念。

Spring IoC容器负责创建Bean,并通过容器将功能类Bean注入到你所需要的Bean中。Spring提供使用xml、注解、Java配置、groovy配置实现Bean的创建和注入。

无论是xml配置哦、注解配置还是Java配置,都称为配置元数据,所谓元数据即描述数据的数据。元数据本身不具备任何可执行能力,只能通过外界代码对这些元数据进行解析后进行一些有意义的操作。Spring容器解析这些配置元数据进行Bean初始化、配置和管理依赖。

       

@Autowire、@Inject、@Resource可注解在set方法或者属性上,常用是注解在属性上,优点是代码更少,层次更清晰。

2.  示例

本节演示基于注解的Bean初始化和依赖注入,Spring容器选AnnotationConfigApplicationContext 

      

     

     

1.3.2  Java配置

1.  点睛

Java配置是Spring 4.x推荐的配置,也是SpringBoot推荐使用的配置,可以完全代替xml配置。

Java配置是通过@Configuration和@Bean实现的。

本文通篇使用Java配置和注解混合配置。

使用原则:全局配置使用Java配置(例如数据库相关配置、MVC相关配置),业务Bean的配置使用注解配置(@Service、@Component、@Repository、@Controller)

2.  示例

本节介绍Java配置。

1.3.3  AOP

1.  点睛

AOP即面向切面编程,Spring的AOP存在的目的是解耦合,让一组类共享相同的行为。

Spring支持AspectJ的注解切面式编程。

2.   示例

本节演示基于注解和基于方法规则拦截两种方式,演示一种模拟记录操作的日志系统的实现。其中,注解拦截能够很好的控制拦截粒度和获得更丰富的信息,Spring本身在事务处理(@Transcational)和数据缓存(@Cacheable)上面都使用此种形式的拦截。


第2章  Spring常用配置

2.1  Bean的Scope

2.1.1  点睛

Scope描述的是Spring容器是如何创建Bean实例的,通过@Scope注解实现,Spring的Bean的Scope有以下几种:

  • Singleton:  一个Spring容器只有一个Bean实例,此为Spring的默认配置,全容器共享一个实例。

  • Prototype: 每次调用创建一个新的Bean实例。

  • Request: Web项目中,给每一个http request新建一个Bean实例。

  • Session: Web项目中,给每一个http session新建一个Bean实例。

  • GlobalSession: 这个只在portal应用中有用,给每一个个global http session新建一个Bean实例。

此外,SpringBatch中还有一个Scope是使用@StepScope。

2.1.2  示例

2.2  Spring EL和资源调用

2.2.1  点睛

Spring EL即Spring 表达式语言,允许在xml或者注解中使用表达式。

Spring开发中,经常涉及调用各种资源的情况,包括普通文件,网址,配置文件,系统环境变量等,此时可以使用Spring EL实现资源注入。

Spring主要在注解@Value中使用语言表达式。

2.2.2  示例

本节演示以下几种情况:注入普通字符、注入操作系统属性、注入表达式运算结果、注入其他Bean的属性、注入文件内容、注入网址内容、注入属性文件。

2.3  Bean的初始化和销毁

2.3.1  点睛

在实际开发中,经常会遇到在Bean使用之前或者之后进行一些必要的操作,Spring对Bean的生命周期的操作提供了支持。在使用Java配置和注解配置提供了如下两种方式:

(1)Java配置方式:使用@Bean的initMethod和destroyMethod(相当于xml配置的init-method和destroy-method)

(2)注解方式:利用JSR-250的@PostConstruct和@PreDestroy。

2.3.1  示例

2.4  Profile

2.4.1  点睛

profile为不同环境使用不同配置提供了支持,(例如开发环境、生产环境的配置不同,如数据库配置)

      

            

             

2.4.2  示例

2.5  事件(Application Event)

2.5.1  点睛

Spring的事件为Bean与Bean之间的消息通信提供了支持。当一个Bean处理完一个任务之后,需要另外一个Bean做一些相应处理,那么需要另外的Bean监听当前Bean所发出的事件。

Spring的事件需要遵循如下流程:

      

2.5.2  示例

第3章  Spring高级话题

3.1  Spring Aware

3.1.1  点睛

Spring的依赖注入最大的亮点是你所有的Bean对Spring容器的存在是没有意识的,也就是说你可以把容器替换成其他的容器,例如Google Guice,这时Bean之间的耦合度很低。

但是在实际的项目中,不可避免的要用到Spring容器本身的功能资源,这时Bean必须意识到Spring容器的存在,才能调用Spring所提供的资源,这就是所谓的Spring Aware。

其实,Spring Aware本来就是Spring设计用来框架内部使用的,若使用了Spring Aware 你的Bean将会和Spring框架耦合。

Spring提供的Aware接口如下:

Spring Aware 的目的是为了让Bean获得Spring容器的服务。因为ApplicationContext接口集成了MessageSource接口、ApplicationEventPublisher接口和ResourceLoader接口,所以Bean继承ApplicationContextAware可以获得Spring容器的所有服务,原则上还是用到什么接口,就实现什么接口。

3.1.2  示例

3.2  多线程

3.2.1  点睛

Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现基于线程池的TaskExecutor。而实际开发中任务一般是非阻塞的,即异步的,所以要在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean的方法中使用@Async注解来声明其是一个异步任务。

3.2.2  示例

3.3  计划任务

3.3.1  点睛

从Spring3.1开始,计划任务在Spring中实现变得异常简单。首先通过在配置类注解@EnableScheduling来开启对计划任务的支持,然后在要执行的计划任务的方法上注解@Scheduled声明一个计划任务。

3.3.2  示例

3.4  条件注解@Conditional

3.4.1  点睛

在2.4介绍通过活动的profile,可以创建不同的Bean。Spring4提供了一个更通用的基于条件的Bean的创建,即使用@Conditional注解,该注解根据满足某一特定条件创建一个特定Bean。例如,当某一个jar包在一个类路径下的时候,自动配置一个或者多个Bean;或者只有某个Bean被创建才会创建另外一个Bean。总的来说,就是根据特定的条件来控制Bean的创建行为,利用这个特性可以进行一些自动的配置。

3.4.2  示例

下面以不同操作系统为条件,通过实现Condition接口并重写其matches方法来构造判断条件。若Windows系统下运行程序,则输出列表命令dir;若在Linux 操作系统下运行程序,则输出列表命令ls。

3.5  组合注解与元注解

3.5.1  点睛

Spring注解主要用来配置注入Bean,切面相关配置(@Transactional)。

元注解就是可以注解到别的注解上的注解,被注解的注解称为组合注解,组合注解具备元注解的功能。Spring很多是元注解,而且本身也是组合注解。

3.5.2  示例

3.6  @Enable*注解的工作原理

通过观察这些@Enable*注解的源码,可以发现所有的注解都有一个@Import注解,该注解是导入配置类的,也就意味着这些自动开启的实现是导入一些自动配置的Bean。这些导入配置方式有以下3种类型:

3.6.1  第一类:直接导入配置类

3.6.2  第二类:依据条件选择配置类

3.6.3  第三类:动态注册Bean

3.7  测试

3.7.1  点睛

3.7.2  示例


                                 第二部分

                         点睛SpringMVC 4.X


第4章  SpringMVC 基础

Zeroturnaround(知名热部署软件JRebel厂商)统计世界范围内流行的框架:

从上图能看上目前SpringMVC的的流行程度,在vitalflux.com统计了2014 - 2015年10佳Web框架排名:

1、SPringMVC  2. Grails  3.Play   4.SpringBoot  5.Vaadin

可见SpringMVC是Web框架的霸主。

4.1  SpringMVC概述

MVC就是模型(Model)、视图(View)、控制器(Controller)。三层架构是表现层、应用层、数据访问层。MVC实际上只存在三层架构的表现层。

三层架构是整个应用的架构,由Spring进行管理。一般项目的Service层、DAO层反映在应用层、数据访问层。

4.2  SpringMVC项目快速搭建

4.2.1  点睛

Spring MVC提供了一个DistpatcherServlet来开发Web应用。在Servlet2.5及以下的时候在web.xml下配置元素即可。本节将使用Servlet3.0 + 无web.xml的配置方式,在SpringMVC里实现WebApplicationInitializer接口便可以实现等同于web.xml的配置。

4.2.2  示例

4.3  Spring MVC的常用注解

4.3.1  点睛

Spring MVC常用注解如下:

      

       

4.3.2  示例

4.4  Spring MVC基本配置

Spring的定制配置要求配置类继承一个WebMvcConfigurerAdapter类,并在配置类使用@EnableWebMvc注解,来开启对Spring Mvc配置的支持。

4.4.1  静态资源映射

4.4.2  拦截器配置

4.4.3  @ControllerAdvice

4.4.4  其他配置

4.5  Spring MVC高级配置

4.5.1  文件上传配置

4.5.2  自定义HttpMessageConverter

4.5.3  服务器端推送技术

4.6  SpringMVC测试

4.6.1  点睛

4.6.2  示例


                                 第三部分

                          实战Spring Boot


第5章  Spring Boot 基础

5.1  Spring  Boot基础

5.1.1  什么是Spring Boot

5.1.2  Spring Boot核心功能

5.1.3  Spring Boot优缺点

优点:快速构建项目;对主流开发框架的无配置继承;项目可以独立运行,无须外部依赖Servlet容器;提供运行时的应用监控;极大地提高了开发效率、部署效率;与云计算的天然继承。

缺点:书籍文档较少;

5.1.4  关于本文Spring Boot版本

本文以Spring Boot 1.3.0作为演示。

5.2   Spring Boot快速搭建

5.2.1  http://start.spring.io

5.2.2  Spring Tool Suite

5.2.3  IntelliJ IDEA

5.2.4  Spring Boot  CLI

5.2.5  maven手工构建

5.2.6  简单演示

第6章  Spring Boot核心

6.1  基本配置

6.1.1  入口类和@SpringBootApplication

6.1.2  关闭特定的自动配置

6.1.3  定制Banner

6.1.4  Spring Boot配置文件

6.1.5  starter pom

6.1.6  使用xml配置

6.2  外部配置

SpringBoot允许properties文件、yaml文件或者命令行参数作为外部配置,

6.2.1  命令行参数

6.2.2  常规属性配置

6.2.3  类型安全的配置(基于properties)

6.3  日志配置

6.4  Profile配置

6.5  Spring Boot运行原理

6.5.1  运作原理

6.5.2  核心注解

6.5.3  实例分析

6.5.4  实战

第7章  Spring Boot的web开发

Web开发的核心内容是内嵌Servlet容器和Spring MVC。

7.1  Spring Boot的Web开发支持

7.2  Thymeleaf模板引擎

7.2.1  Thymeleaf基础知识

7.2.2  与Spring MVC集成

7.2.3  Spring Boot的Thymeleaf支持

7.2.4  实战

7.3  Web相关设置

7.3.1  Spring Boot提供的自动配置

查看WebMvcAutoConfiguration及WebMvcProperties源码,可以发现Spring Boot提供了如下的自动配置:

1. 自动配置的ViewResolver

(1) ContentNegotiatingViewResolver

ContentNegotiatingViewResolver是Spring MVC提供的特殊ViewResolver,它不是自己处理view而是代理给不同的ViewResolver来处理不同的View,所以它有最高的优先级。

(2)BeanNameViewResolver

在控制器(@Controller)中的一个方法的返回值的字符串(视图名)会根据BeanNameViewResolver去查找Bean的名称为返回字符串的view来渲染视图。为了方便理解,举例如下:

(3) InternalResourceViewResolver

InternalResourceViewResolver是极其常用的ViewResolver,主要通过设置前缀、后缀,以及控制器中方法来返回视图的字符串,以得到实际页面,SpringBoot的源码如下:

2.  自动配置的静态资源

在自动配置类的addResourceHandlers方法中定义了以下静态资源的自动配置。

(1)类路径文件

把类路径下的 /static 、/public、/resources和 /META-INF/resources文件夹下的静态文件直接映射为 /** ,可以通过http://localhost:8080/**来访问。

(2)webjar

webjar就是将我们常用的脚本框架封装在jar包中的jar包。

把webjar的 /META-INF/resources/webjars下的静态文件直接映射为 /webjar/** ,可以通过http://localhost:8080/webjar/**来访问。

3.  自动配置的Formatter和Converter

关于自动配置Formatter和Converter,可以看一下WebMvcAutoConfiguration类中的定义:

从代码可以看出,只要定义了Converter、GenericConverter和Formatter接口的实现类的Bean,这些Bean就会自动注册到Spring MVC中。

4. 自动配置的HttpMessageConverters

在WebMvcAutoConfiguration中,我们注册了messageConverters,代码如下:

5.  静态首页的支持

把静态index.html文件放置在如下目录。

当访问应用根目录http://localhost:8080/时,会直接映射。

7.3.2  接管SpringBoot的Web配置

如果Spring Boot提供的SpringMVC不符合要求,则可以通过一个配置类(注解有@Configuration的类)加上@EnableWebMvc注解来实现完全自己控制的MVC配置。

当然,SpringBoot的自动配置是符合我们大多数的需求。在你既需要保留SpringBoot提供的便利,又需要增加自己的额外的配置的时候,可以定义一个配置类并集成WebMvcConfigurerAdapter,无须使用@EnableWebMvc注解,然后按照第4章的SpringMVC的配置方法来添加SpringBoot为我们所做的其他配置,例如:

值得指出的是,在这里重写的addViewControllers方法,并不会覆盖WebMvcAutoConfiguration中的addViewControllers(在此方法中,SpringBoot将“/”映射值index.html),这就意味着自己的配置SpringBoot的自动配置同时生效,这也是推荐添加自己的MVC配置的方式。

7.3.3  注册Servlet、FIlter、Listener

当使用嵌入式的Servlet容器(Tomcat、Jetty等)时,以将Servlet、Filter和Listener声明为Spring Bean而达到注册的效果;或者注册ServletRegistrationBean、FilterRegistrationBean和ListenerRegistrationBean的Bean。

7.4  Tomcat配置

本节虽然叫Tomcat配置,其实指的是servlet容器的配置,因为Spring Boot默认内嵌的Tomcat为Servlet容器。本文只对Tomcat配置进行讲解,对于Jetty、Undertow都是通用的。

7.4.1  配置Tomcat

关于Tomcat的所有属性都在org.springframework.boot.autoconfigure.web.ServerProperties配置类中做了定义,只需要在application.properties配置属性做配置即可。通用的Servlet容器配置都以“server”作为前缀,而Tomcat特有配置都以“server.tomcat”作为前缀。

7.4.2 代码配置Tomcat

如果需要通过代码配置servlet容器,则可以注册一个实现EmbeddedServletContainerCustomizer接口的Bean。若想直接配置Tomcat、Jetty、Undertow,则可以直接定义TomcatEmbeddedServletContainerCustomizer、JettyEmbeddedServletContainerCustomizer、UndertowEmbeddedServletContainerCustomizer

7.4.3  替换Tomcat

Spring Boot默认使用Tomcat作为内嵌Servlet容器,查看spring-boot-starter-web依赖,如下图所示:

如果需要使用Jetty或者Undertow作为servlet容器,只需要修改spring-boot-starter-web依赖即可。

7.4.4  SSL配置

7.5  Favicon配置

7.5.1  默认的Favicon

Spring Boot提供了一个默认的Favicon,每次访问应用的时候都能看到。

7.5.2  关闭Favicon

可以在application.properties中设置关闭Favicon,默认是开启的。

7.5.3  设置自己的Favicon

若需要设置自己的Favicon,则只需要将自己的favicon.ico(文件名不能变动)文件放置在类路径根目录类路径META-INF/resources/类路径resources/ 类路径static/ 或者类路径public/ 下。本文示例将favicon.ico放置在src/main/resources/static下,运行效果如下:

7.6  WebSocket

7.6.1  什么是 WebSocket

7.6.2   Spring Boot提供的自动配置

Spring Boot对内嵌的Tomcat(7或者8)、Jetty9和undertow使用WebSocket提供了支持。配置源码存在于org.springframework.boot.autoconfigure.websocket下,如下图所示:

7.6.3  实战

1、准备

7.7  基于Bootstrap和AngularJS的现代Web应用

7.7.1  Bootstrap 

1、什么是Bootstrap

Bootstrap是开发响应式和移动优先的web应用的最流行的HTML、CSS、JavaScript框架。实现了只使用一套代码就能在不同的设备显示你想要的视图的功能。Bootstrap还为我们提供了大量美观的HTML元素前端组件和jQuery插件。

2、下载并引用Bootstrap

3、CSS支持

Bootstrap的CSS样式为基础的HTML元素提供了美观的样式,此外还提供了一个高级的网格系统来做页面布局。

4、页面组件支持

5、Javascript支持

7.7.2  AngularJS

7.7.3  实战

第8章 SpringBoot的数据访问

Spring Data项目是Spring用来解决数据访问问题的一揽子解决方案。Spring Data是一个伞形项目,包含了大量关系型数据库以及非关系型数据库的数据访问解决方案。Spring Data可以使我们快速而且简单地使用普通的数据访问技术以及新的数据访问技术。

Spring Data包含的子项目如下表所示:

Spring Data为我们使用统一的API来对上述的数据存储技术进行数据访问提供了支持。这是Spring通过提供Spring Data Commons项目来实现的,它是上述各种SpringData项目的依赖。Spring Data Commons让我们在使用关系型以及非关系型数据访问技术时都能使用基于Spring的统一标准,该标准包括CRUD(创建、获取、更新、删除)、查询、排序和分页的相关的操作。

此处介绍一下Spring Data Commons的一个重要概念:Spring Data Repository抽象。使用Spring Data Repository可以极大地减少数据访问层的代码。既然是数据访问操作的统一标准,那么肯定定义了各种各样和数据访问相关的接口,Spring Data Repository抽象的根接口是Repository接口:

从源码可以看出,它接受领域类(JPA为实体类)和领域类的id类型作为类型参数。

它的子接口CrudRepository定义了和CRUD操作相关的内容:

CrudRepository的子接口PagingAndSortingRepository定义了与分页和排序操作相关的内容:

不同的数据访问技术也提供了不同的repository,例如Spring Data JPA有JPARepository、Spring DataMongoDB有MongoDBRepository。

Spring Data 项目还给我们提供了一个激动人心的功能,即可以根据属性名进行计数、删除、查询方法等操作,例如:

8.1  引入Docker

Docker是一个轻量级容器技术,类似于虚拟机技术。Docker是直接运行在当前操作系统(Linux)之上,而不是运行在虚拟机中,但是也实现了虚拟机技术的资源隔离,性能远远高于虚拟机技术。

Docker 支持将软件编译成一个镜像,在这个镜像里做好对软件的各种配置,然后发布这个镜像,使用者可以运行这个镜像,运行中的镜像称为容器。容器的启动非常快,一般是以秒为单位。

8.1.1  Docker的安装

因为Docker的运行原理是基于Linux的,所以Docker只能在Linux下运行。在开发测试阶段,可以在Windows或者Mac OS X系统下运行虚拟机VirtualBox,在此虚拟机里面运行Docker。

8.1.2  Docker常用命令及参数

8.1.3  下载本文所需的Docker镜像

8.1.4  异常处理

8.2  Spring Data JPA

8.2.1  点睛Spring Data JPA

1、什么是Spring Data  JPA

JPA即Java  Persistence API,JPA是一个基于ORM的标准规范。JAP的主要实现有Hibernate、EclipseLink、OpenJPA等,这就意味着我们只要使用JP来开发,无论使用哪一种开发方式都是一样的。

Spring Data JPA是Spring Data的一个子项目,它通过提供基于JPARepository极大地减少了JPA作为数据访问方案的代码量。

2、定义数据访问层

使用Spring Data JPA建立数据访问层十分简单,只需要定义一个继承JPARepository的接口即可,定义如下:

继承JpaRepository接口意味着已经有以下的数据访问操作方法:

3、配置使用Spring Data JPA

在Spring环境中,使用Spring Data JPA可以通过@EnableJpaRepositories注解来开启Spring Data JPA的支持,@EnableJpaRepositories接收的value参数用来扫描数据访问层所在包下的数据访问的接口定义。

4、定义查询方法

8.2.2  SpringBoot的支持

1、JDBC的自动配置

2、对JPA的自动配置

3、 Spring Data JPA的自动配置

4、Spring Boot下的Spring Data JPA

8.2.3  实战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会编程的小猴子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值