《Maven实战》笔记整理

目录

第一章:Maven简介

(1.1)何为Maven

(1.2)其他构建工具

第二章:Maven的安装和配置

(2.1)安装和配置

(2.2)配置文件

(2.3)Maven的文件目录

第三章:Maven使用入门

(3.1)生命周期

(3.2)如何生成可执行jar包

(3.3)项目骨架

第五章:坐标和依赖

(5.1)Maven的坐标

 (5.2)Maven依赖

(5.3)依赖范围

(5.4)Maven的传递性依赖性质

(5.5)可选依赖 

(5.6)排除依赖

(5.7)归类依赖

(5.8)优化依赖

第六章:仓库

(6.1)Maven仓库和布局

(6.2)仓库的分类

(6.3)本地仓库

(6.4)远程仓库:【中央仓库】,【私服】,【其他公开的远程仓库】

(6.5)如何配置【远程仓库】:在pom.xml中添加 标签

(6.6)如何验证【远程仓库】:settings.xml中配置 标签

(6.7)如何把本地项目部署到【远程仓库】:pom.xml文件配置和标签

(6.8)如何配置镜像:settings.xml中配置标签,代替某些的url 

(6.9)快照版本

(6.10)仓库搜索服务

第七章:声明周期和插件

(7.1)三套生命周期

(7.2)Maven插件

第八章:聚合与继承

(8.1)聚合:标签

(8.2)继承:标签

(8.3)父子pom的依赖管理: 

(8.4)超级pom

(8.5)约定优于配置

(8.6)反应堆(Reactor)


第一章:Maven简介

(1.1)何为Maven

  • 构建工具,依赖管理工具,项目信息管理工具
  • 提供免费的中央仓库
  • 约定优于配置

(1.2)其他构建工具

  • IDE:如Eclipse,Idea
  • Make:最早的构建工具,Makefile的语法
  • Ant:Another Neat Tool(另一个整洁的工具),最早用来构建Tomcat。与Maven类似,但是不提供依赖管理

第二章:Maven的安装和配置

(2.1)安装和配置

(2.2)配置文件

  • $M2_HOME/conf/settings.xml
    • 全局范围的,整台机器的所有用户都会受到该配置的影响
  • ~/.m2/settings.xml
    • 推荐使用!!!
    • 用户级别的,不影响其他用户
    • 升级Maven不需要重新配置

(2.3)Maven的文件目录

  • bin:包含mvn的运行脚本,对于win来说,是.bat文件
  • boot:只包含一个jar文件,Maven使用其加载自己的类库,对用户来说,不用关心该文件
  • conf:包含非常重要的settings.xml文件。一般情况下更倾向于复制到~/.m2/目录下,在用户范围内定制Maven的行为
  • lib:包含Maven运行时需要的Java类库,以及Maven内置的超级POM

第三章:Maven使用入门

(3.1)生命周期

  • mvn clean:清理 target/
  • mvn compile:编译项目主代码,到 target/classes 目录
  • mvn test:
  • mvn package:打包,如果POM中没有指定,默认打jar包,位于target/目录中
  • mvn install:将jar包安装到本地repository

(3.2)如何生成可执行jar包

  • 默认打包生成的jar包是不能直接运行的,为了生成可执行的jar包,需要用到 maven-shade-plugin 插件

(3.3)项目骨架

  • Maven中的pom.xml对应于Make中的Makefile,Ant中的build.xml。
  • Maven项目的一些约定:src/main/java 目录下放置项目的主代码,src/test/java 目录下放置项目的测试代码,这些基本目录结构和pom.xml被称为项目的骨架
  • 快速创建项目骨架
    • 首先执行命令:mvn archetype:generate
    • 接着按提示输入:groupId, artifactId, version, package

  

第五章:坐标和依赖

(5.1)Maven的坐标

  • groupId(必须定义):不关键,比如com.dianping.zebra,或者 com.sankuai.meituan
  • artifactId必须定义:项目中的一个模块,推荐用模块名,比如xy-trade-microloan-thrift-api,或者 zebra-client
  • version(必须定义):版本,比如 2.9.2-SNAPSHOT
  • packaging(可选定义):定义了maven的打包方式,不定义packaging时默认jar包,当然也可以定义war包
  • scope(可选定义):作用范围,默认为compile。如果<scope>test</scope>,表示只能在测试代码中import该依赖,主代码依赖会报错
  • classifier(不能直接定义):定义一些附属组件,比如【javadoc文档】和【sources源代码】

 (5.2)Maven依赖

<dependencies>
	<dependency>
    	<groupId>com.dianping.zebra</groupId>
        <artifactId>zebra-client</artifactId>
        <version>2.9.2-SNAPSHOT</version>
    </dependency>
   					
	<dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <version>2.0.2</version>
        <scope>test</scope>
    </dependency>
<dependencies>
  • <groupId>,<artifactId>,<version>:依赖的基本坐标,Maven需要根据坐标才能找到依赖
  • <type>(可选,默认为jar):依赖的类型,大多数情况下不必声明,默认为jar
  • <scope>:依赖范围,见(3)
  • <optional>:标记依赖是否可选,见(5)
  • <exclusions>:排除传递性依赖,见(6)

(5.3)<scope>:依赖范围

  • 概述:用来控制依赖与这三种classpath(编译,测试,运行)的关系,有以下几种选择
    • compile(默认):在【编译,测试,运行】时都使用该依赖。比如spring-core(都需要用到)
    • test:只对【test文件夹下】有效,在编译主代码或者运行项目时无法使用此类依赖。比如JUnit,mockito(只有在单元测试才用到这些依赖)
    • provided:已提供该依赖。对于【编译和测试】有效。在运行时无效。
    • runtime:对【测试和运行】有效,编译主代码时无效。典型的例子是JDBC驱动实现
    • system:类似provided,但是provided可以通过本地maven仓库解析,system往往与本机系统绑定
    • import:导入依赖范围,后面解释dependencyManagement时再介绍

(5.4)Maven的传递性依赖性质

  • 何为依赖传递:【我的项目A】依赖【spring-core】,【spring-core】pom.xml中依赖【commons-logging】。则 【我的项目A】依赖【commons-logging】
  • 依赖传递的范围:【我的项目A】依赖scope=test【spring-core】,【spring-core】依赖scope=compile【commons-logging】。则【我的项目A】依赖scope=test【commons-logging】
  • 依赖的规则:第一原则优先,相同则采用第二原则
    • 第一原则:依赖路径越短越优先。比如:A->B->C->X(1.0);A->D->X(2.0)。由于X(2.0)的路径短,X(2.0)会被解析使用
    • 第二原则:看pom.xml中的依赖顺序,谁写在上面谁先依赖。比如A->B->Y(1.0);A->C->Y(2.0)。如果pom.xml文件中B写在C的上面,则Y(1.0)会被解析使用

(5.5)<optional>:可选依赖 

  • 配置 <optional> true </optional> ,则该依赖为【可选依赖】
  • 【可选依赖】有什么用:不具有传递性
    • 比如:A->B,B->mysql.jar(可选),B->oracle.jar(可选)。
    • 则依赖不会传递,即 A不会依赖mysql.jar和oracle.jar。换句话说:项目里没有mysql.jar和oracle.jar不会对A产生任何影响
  • 为什么要【可选依赖】
    • 假如项目B实现了两个特性,其中的特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用这两个特性
    • 比如B是一个持久层隔离工具包,特性一用于mysql,特性二用于oracle,这两者是互斥的,究竟用哪个,让用户自己来手动选(手动引入)
  • 例子:B的pom.xml(图一),用户如果要用mysql的jar包,需要在A中自己手动引(下图)
    • 图一:

    • 图二:

(5.6)<exclusion>:排除依赖

  • 假如项目里有个第三方依赖,该依赖还依赖了另一个1.0.0-SNAPSHOT版本的库,那么该1.0.0-SNAPSHOT就会成为当前项目的传递性依赖。此时我想排除该依赖,则要使用<exclusion>标签

  • 需要注意的是:声明exclusion时候只需要groupId和artifactId,不需要version(显然,根据前两者就可以在pom.xml中唯一确定一个Maven坐标了)

(5.7)<properties>:归类依赖

  • 假如项目里有很多Spring Framework的依赖(如下),你希望保持它们版本号一致,并且统一管理它们的版本
    • org.springframework:spring-core:2.5.6
    • org.springframework:spring-beans:2.5.6
    • org.springframework:spring-context:2.5.6
    • org.springframework:spring-context-support:2.5.6
  • 使用<properties>标签

(5.8)优化依赖

  • 可以通过命令查看项目中的所有依赖和依赖关系
    • 显示所有已解析依赖:mvn dependency:list
    • 查看解析后的依赖树:mvn dependency:tree
    • 分析当前的项目依赖:mvn dependency:analyze

第六章:仓库

(6.1)Maven仓库和布局

  • 何为仓库:Maven将所有【构建完成的jar包】安装部署到【Maven本地仓库】,防止浪费磁盘空间,并供各个项目调用
  • Maven中【jar包路径】和【坐标】的关系:groupId/artifactId/version/artifactId-version.packaging,例子如下

(6.2)仓库的分类

  • 只分为两类:【本地仓库】和【远程仓库】,一个用户只有一个【本地仓库】,但是可以配置多个【远程仓库】
  • jar查找规则
    • (1)先从【本地仓库】找
    • (2)找不到再去【远程仓库】下载到【本地仓库】
    • (3)如果都没有则报错

(6.3)本地仓库

  • 默认配置下,【本地仓库】的路径为:用户目录/.m2/repository/...
    • 比如Windows:C:\Users\jyy\.m2\repository\
  • 如何更改【本地仓库】地址
    • 将 $M2_HOME/conf/settings.xml 文件复制到 ~/.m2/settings.xml,并增加一行<localRepository> 标签配置。不过不推荐这个方式,因为不推荐修改全局目录的settings.xml文件
  • 如何安装【本地Maven项目】到【本地仓库】
    • 命令:mvn clean install

(6.4)远程仓库:【中央仓库】,【私服】,【其他公开的远程仓库】

  • 【Maven中央仓库】:【Maven】自带的远程仓库,包含了绝大部分开源的构件:https://mvnrepository.com/
    • Maven的安装文件自带【中央仓库】的配置,可以通过 $M2_HOME/lib/maven-model-builder-3.0.jar中的 org/apache/maven/model/pom-4.0.0.xml看到,该pom文件是一个超级POM,所有Maven项目都会继承
  • 私服:架设在局域网内,代理外部广域网上的远程仓库
    •  jar包查询规则:先找【本地仓库】,再找【私服】,找不到再找【远程仓库】
    • 为什么需要私服:
      • 有些jar包是公司内部用的,不开源,可以放在私服
      • 如果Internet不稳定,私服提高了稳定性
    • 比较著名的有:Nexus
  • 其他公开的远程仓库
    • 常见的有 Java.net Maven库,JBoss Maven库

(6.5)如何配置【远程仓库】:在pom.xml中添加 <repositories> 标签

  • <id>:必须是唯一的,Maven自带的中央仓库使用的id为central,如果其他仓库id声明也使用central,则会覆盖中央仓库的配置
  • <name>:名称,随便去取
  • <url>:仓库地址,一般是http协议格式,可以在浏览器中打开
  • <releases>和<snapshots>标签
    • <enabled>
      • snapshots的<enabled>为false,表示不允许从 JBoss仓库下载【快照版本】的jar包
      • releases 的 <enabled>为true,表示可以从 JBoss仓库下载【发布版本】的jar包
    • <updatePolicy>:从Maven远程仓库检查更新的频率,3种选择
      • never(从不检查更新)
      • always(每次都检查)
      • X(每隔X分钟检查一次)
    • <checksumPolicy>:检查策略,3种选择
      • warn(出错则输出warn警告)
      • fail(出错则构建失败)
      • ignore(完全忽略检验失败)
    • 例子:

  • <layout>:default表示仓库的布局是Maven2和Maven3的默认布局

(6.6)如何验证【远程仓库】:settings.xml中配置 <servers> 标签

  • 有时候,远程仓库只有部分人员能访问,需要配置用户名和密码才能访问,需要在Maven的settings.xml中配置

  • 需要注意的是,<id>必须与前面pom.xml中<repository>的id相同

(6.7)如何把本地项目部署到【远程仓库】:pom.xml文件配置<repository>和<snapshotRepository>标签

<distributionManagement>
    <repository>
        <id>myCompany-nexus-releases</id>
        <name>myCompany Nexus Repository</name>
        <url>http://xxx.xxxxxxx.com/repository/releases</url>
    </repository>
    <snapshotRepository>
        <id>myCompany-nexus-snapshots</id>
        <name>myCompany Nexus Repository</name>
        <url>http://xxx.xxxxxxx.com/repository/snapshots</url>
    </snapshotRepository>
</distributionManagement>
  • <project>中的<distributionManagement>标签
    • <repository>表示:releases版本的仓库地址
    • <snapshotRepository>表示:snapshots版本的仓库地址
    • <id>标签必须要与 settings.xml中的id一致
  • 需要注意的是,如果如果该repository需要用户名密码的话,需要配合(5)中的<servers>标签使用
  • 配置好之后:mvn clean deploy命令会自动部署到远程仓库

(6.8)如何配置镜像:settings.xml中配置<mirror>标签,代替某些<repository>的url 

  • 何为镜像:就比如,阿里云提供了Maven仓库的国内镜像,国内用户下载起来会更快(https://maven.aliyun.com/repository/public
  • 例1:下图的<mirrorOf>为central,表示用该url替代了【Maven中央仓库】,所有去中央仓库的请求都会转到该url
  • 例2:下图的<mirrorOf>为*,表示用该url替代了所有<repository>的配置,所有配置的<repository>都会转到该url镜像
    •  如果该镜像需要认证,则去settings.xml中配置<server>即可
  • <mirrorOf>的用法
    • <mirrorOf> * </mirrorOf>:匹配所有远程仓库
    • <mirrorOf> external:* </mirrorOf>:匹配所有远程仓库,但是 locolhost 和 file://协议的除外,即匹配所有不在本机上的远程仓库
    • <mirrorOf> repo1, repo2 </mirrorOf>:匹配 repo1 和 repo2
    • <mirrorOf> *, !repo1 </mirrorOf>:匹配所有远程仓库, repo1除外(感叹号表示排除)

(6.9)快照版本

  • 为何需要snapshot版本

(6.10)仓库搜索服务

  • 推荐几个强大的公共Maven仓库
    • Sonatype Nexus:Nexus是目前最流行的开源Maven仓库管理平台,可以用它架设私服
    • Javaana
    • MVNbrowser
    • MVNrepository

第七章:声明周期和插件

(7.1)三套生命周期

  • Maven拥有3套相互独立的生命周期:分别是 clean(清理项目),default(构建项目),site(建立项目站点)
  • clean生命周期:主要用于清理项目
    • 1.1)pre-clean:执行清理前需要完成的工作
    • 1.2)clean:清理上一次构建生成的文件
    • 1.3)post-clean:执行清理后需要完成的工作
  • default声明周期:三套生命周期中最核心的部分
    • 验证和初始化
      • 2.1)validate
      • 2.2)initialize
    • src/main/resources 处理和编译
      • 2.3)generate-sources
      • 2.4)process-sources:处理项目的主资源文件:一般来说,对src/main/resources 目录的内容进行变量替换等工作,复制到项目输出的主classpath目录中
      • 2.5)generate-resources
      • 2.6)process-resources
      • 2.7)compile:编译项目的主源码:一般来说,是编译 src/main/java 目录下的Java文件至项目输出的主classpath目录中
      • 2.8)process-classes
    • src/test/resources 处理和编译
      • 2.9)generate-test-sources
      • 2.10)process-test-sources:处理项目的测试资源文件:一般来说,对src/test/resources 目录的内容进行变量替换等工作,复制到项目输出的测试classpath目录中
      • 2.11)generate-test-resources
      • 2.12)process-test-resources
      • 2.13)test-compile:编译项目的测试源码:一般来说,是编译 src/test/java 目录下的Java文件至项目输出的测试classpath目录中
      • 2.14)process-test-classes
    • 运行测试代码
      • 2.15)test:使用单元测试框架进行测试,测试代码不会被打包或者部署
    • 打包,安装,部署
      • 2.16)prepare-package
      • 2.17)package:接受编译好的代码,打包可发布的格式,比如jar
      • 2.18)pre-integration-test
      • 2.19)integration-test
      • 2.20)post-integration-test
      • 2.21)verify
      • 2.22)install:将包安装到Maven本地仓库,供本地其他Maven项目使用
      • 2.23)deploy:将包部署到远程仓库
  • site声明周期:主要目的是建立和发布项目站点
    • pre-site
    • site
    • post-site
    • site-deploy:将生成的项目站点发布到服务器上

(7.2)Maven插件

  • Maven的核心仅仅是定义了生命周期,具体的任务由插件完成。如maven-dependency-plugin
  • 在repository/org/apache/maven/plugins目录下,可以看到一些下载好的插件 
  • 什么是插件目标 
    • compiler:compile(maven-compiler-plugin的compile目标)
    • surefire:test(maven-surefire-plugin的test目标)
  • 插件绑定
    • 为了让用户不需要配置就能构建Maven项目,Maven在其主要生命周期绑定了很多插件的目标 
  • 自定义插件
    • 如果有这样一个需求:创建项目的【源码jar包】
    • maven-source-plugin可以完成该需求,需要在pom文件中自行配置
    • <exclusions>下每个<exclusion>子元素可以用来配置执行一个任务
    • <id>:该例中配置了一个id=attach-sources的任务
    • <phase>:通过phase配置,将其绑定到verify生命周期阶段上
    • <goal>:指定要执行的插件目标
      • 可选:jar(对源码进行打包),jar-test(对test中的测试代码进行打包)
    • 运行 mvn verify 会看到以下输出:表示 maven-source-plugin:jar-no-fork 得以执行
    • 例子:
      • 这个插件表示:在生命周期中的generate-test-resources阶段,将代码打成jar包
  • 插件配置参数
    • (1)命令行配置(常用)
      • 常见形式:使用-D参数,伴随 key=value 形式
        • mvn install -Dmaven.test.skip=true
    • (2)pom.xml中全局配置
      • 比如,配置compile时生成java1.5的字节码文件

第八章:聚合与继承

(8.1)聚合:<module>标签

  • 比如:存在两个同级的子模块,可以用一个【主pom.xml】管理多个【子pom.xml】
  • 例1:
  • 例2:来自zebra项目的主pom文件
    • <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <groupId>com.dianping.zebra</groupId>
          <artifactId>zebra-all</artifactId>
          <packaging>pom</packaging>
          <version>2.9.1</version>
          <name>zebra-all</name>
          <organization>
              <name>Meituan Dianping</name>
              <url>http://www.dianping.com/</url>
          </organization>
          <modules>
              <module>zebra-dao</module>
              <module>zebra-sample</module>
              <module>zebra-admin-web</module>
              <module>zebra-cat-client</module>
              <module>zebra-client</module>
          </modules>
          <description>zebra</description>
  • 需要用到的标签
    • <packaging>:主pom文件必须声明为pom,否则无法构建(但子pom文件可以不声明packaging,因为默认为jar)
    • <module>:内容为【子pom文件】中的<artifactId> ,即子项目名称
  • 父模块与子模块的结构
    • (1)父子结构:最常用的目录结构
    • (2)平行结构:不太常用,【父pom】中<moudle>中的路径需要变化

(8.2)继承:<parent>标签

  • 为什么要聚合与继承:在所有子模块的【子pom】中,往往会写重复的依赖配置,比如spring-core, spring-beans等等
  • 【子pom】如何继承【父pom】:<parent>标签
    • 需要注意的是:一般采用【父子目录结构】无需声明<relativePath>,<relativePath>默认值是 ../pom.xml
    • 这里的例子中没有为 account-email 声明 groupId 和 version,则默认采用父pom的。如果子模块需要和父模块不一样,则需要显示声明。
    • 子模块的<artifactId>应该显示声明,因为它肯定得与父模块不一样
  • 哪些标签可以被继承

(8.3)父子pom的依赖管理:<dependencyManagement> 

  • <dependencyManagement>能让子模块继承到父模块的依赖配置,但<dependencyManagement>的依赖声明不会引入实际的依赖
  • 父模块的pom.xml:
  •  子模块的pom.xml:
    • ​​
  • 如上所示:<dependencyManagement>不会给【父模块】和【子模块】引入依赖,不过这段配置是会被继承的
  • dependencyManagement中的依赖版本会覆盖传递依赖版本
    • 举个例子:项目中依赖的A,A依赖了B的1.0版本。如果在dependencyManagement中显示声明依赖B的2.0版本,那么A也会去依赖B的2.0版本 
  • 对于子模块
    • 如果需要依赖:只需要配置groupId和artifactId。而version不需要写,只需要委托给父类管理就行了
    • 如果不需要依赖:在子pom.xml中不写就行了,不写就不会引入

(8.4)超级pom

  • 超级pom的坐标:对于Maven3,超级pom的目录为:maven/lib/maven-model-builder-x.x.x.jar中
  • 超级pom中定义了什么?
    • (1)定义了【默认中央仓库】和【插件仓库】
    • (2)定义了【主代码/测试 输出目录】,【主代码输出目录】,【最终构件的名称格式】等等
    • (3)定义了【Maven内置插件】的默认版本

(8.5)约定优于配置

  • Maven提倡约定优于配置(Convention Over Configuration):在maven中只需要简单的配置pom文件,就可以实现 清除构建目录、创建目录、编译代码、复制依赖至目标目录,最后打包
  • maven约定如下
    • 源码目录为 src/main/java
    • 编译输出目录为 target/classes
    • 打包方式为jar
    • 包输出目录为 target

(8.6)反应堆(Reactor)

  • 什么是反应堆:在【父模块】构建项目时,各个【子模块】的构建顺序
  • 构建顺序:并非按照<modules>中的顺序构建,而是根据依赖关系构建 
  • 例子
    • account-aggregator模块中pom.xml中的定义顺序
    • 依赖关系,都依赖parent
    • 在account-aggregator项目下mvn clean install得到的真实构建顺序
      • 先构建【父模块account-parent】,再根据依赖关系自上而下构建【子模块account-email】和【子模块account-persist】
  • 需要注意的是:模块间的依赖关系将反应堆构成一个【有向非循环图】,如果存在循环依赖,Maven会报错
  • 如何裁剪反应堆:即如何【自定义构建】
    • (1)不加参数,默认全部构建:mvn clean install
    • (2)参数-pl,构建某些子模块(按逗号分割):mvn clean install -pl account-email,account-persist
      • 如下所示,可以看到只有指定模块【account-email】和【account-persist】 被构建
    •   (3)参数-am,构建某些子模块以及【子模块所依赖的模块】:mvn clean install -pl account-email -am
      • 如下所示,由于 account-email 依赖 account-parent,所以两者都被构建了
    • (4)参数-amd,构建某些子模块以及【依赖该子模块的模块】:mvn clean install -pl account-parent -amd
      • 由于 account-parent 被 account-email 和 account-persist 依赖,所以三个都被构建

其他

(10.1)maven统一配置资源属性值

  • 需求:jdbc.url这些常用的配置,也用maven作统一管理
  • 方案:
    • (1)在pom.xml中的<properties>中自定义属性
    • (2)在pom.xml中的<build>中添加如下的配置,指定某一moudle下的resources文件夹
    • (3)更常用的写法,在(2)中只能指定某个moudle下的resources文件夹。改成如下格式后,针对每个moudle下的resources文件夹,都能起作用
    • (4)如果想针对test下再做配置,maven也提供了相关标签<testResources>

(10.2)跳过测试

  • 方法一:
  • 方法二:-DskipTests 命令参数

 ​​​​​

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值