五、Java框架之Maven进阶

黑马课程

1. 分模块开发

将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享
例如:订单模块和商品模块。订单必然用到商品,如何使商品中的实体类对订单可见?

1.1 分模块开发入门案例

在这里插入图片描述

示例:抽取domain层

步骤1:新建一个模块

在这里插入图片描述
在这里插入图片描述

步骤2:将原Book模块里的domain里面的实体类复制到新的模块maven_pojo里面,并删除Book模块里的domain

在这里插入图片描述

步骤3:在Book模块中引入maven_pojo的依赖

<!-- 引入其他模块 -->
<!-- maven_pojo实体类模块 -->
<dependency>
    <groupId>org.example</groupId>
    <artifactId>maven_pojo</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

步骤4:将maven_pojo模块打包安装到本地仓库中

在这里插入图片描述

此后即可正常使用

如何使自己本地仓库里的模块给其他人员使用?——私服

示例:抽取dao层

抽取dao层,步骤类似,maven_dao所需的依赖如下

<dependencies>
    <!-- maven_pojo实体类模块 -->
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>maven_pojo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <!-- mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!-- spring-webmvc(含有@Respository注解) -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

1.2 依赖管理

依赖传递

A引入B,B引入C,那么A也引入了C,这就是依赖的传递性

  • 直接依赖:A引入B,B是A的直接依赖
  • 间接依赖:A引入B,B引入C,C是A的间接依赖

依赖冲突

项目引入了同一个依赖的不同版本

  • 路径最短:A和B同时依赖了X,依赖路径最短的会被使用
  • 路径相同时在前者优先:依赖路径相同,在pom中先导入依赖版本被使用

可选依赖

<!-- maven_pojo实体类模块 -->
<dependency>
    <groupId>org.example</groupId>
    <artifactId>maven_pojo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <optional>true</optional>
</dependency>
  • 设置optional为true:对外隐藏当前所依赖的资源,该依赖只在当前模块中使用

在这里插入图片描述

排除依赖

模块A引入模块B,解决依赖冲突时,可选依赖是从模块B入手,排除依赖是从模块A入手

<!-- maven_dao实体类模块 -->
<dependency>
    <groupId>org.example</groupId>
    <artifactId>maven_dao</artifactId>
    <version>1.0-SNAPSHOT</version>
    <exclusions>
        <exclusion>
            <groupId>org.example</groupId>
            <artifactId>maven_pojo</artifactId>
        </exclusion>
    </exclusions>
</dependency>

springmvc_ssm中,通过在 <exclusion>在maven_dao中排除掉maven_pojo中的依赖

依赖冲突问题排查

  • IDEA排查(推荐)
    在这里插入图片描述

  • 打印所有依赖的依赖树

    mvn dependency:tree
    # 可以将依赖树输出到文件中
    mvn -Dverbose  dependency:tree -Doutput=E://depTree.txt
    

2. 聚合和继承

  • 聚合用于快速构建项目,对项目进行管理
  • 继承用于快速配置和管理子项目中所使用jar包的版本
  • 聚合与继承均属于设计型模块,并无实际的模块内容

2.1 聚合

概述

聚合出现背景

  • 前面学习的分模块开发流程
    • 创建模块 – install到本地仓库 – 引入模块
  • 存在的问题
    • 每个创建模块必须 install
    • 模块的任意修改都需要重新 install 一次
    • 假设对ssm_pojo进行了修改,那么所有引用它的项目都需要重新编译一次,可能出现遗漏的项目未编译

聚合就是为了解决上述问题产生的

聚合的思想:通过一个只有pom.xml的空项目,来管理所有的模块,进行自动 install 和 对项目的重新编译

概述

  • 聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合
  • 聚合工程:通常是一个不具有业务功能的"空"工程(有且仅有一个pom文件)
  • 作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建
    • 当工程中某个模块发生更新(变更)时,必须保障工程中与已更新模块关联的模块同步更新,此时可以使用聚合工程来解决批量模块同步构建的问题。

聚合实现步骤

步骤1:创建一个空的maven项目 maven_01_parent

使用01这样的编号更加直观,之前的maven项目也可以改为 maven_02_pojo maven_03_dao

步骤2:在pom.xml中设置打包方式为pom

<packaging>pom</packaging>
  • 默认打包方式:jar
  • web项目打包方式:war
  • 聚合工程打包方式:pom

步骤3:pom.xml添加所要管理的项目

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>maven_01_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <!-- 设置管理的模块名称 -->
    <modules>
        <module>../springmvc_ssm</module>
        <module>../maven_pojo</module>
        <module>../maven_dao</module>
    </modules>
</project>

步骤4:使用聚合统一管理项目

对 maven_01_parent 进行 compile,它会将包括自身在内的4个模块一起编译

在这里插入图片描述

不管pom.xml添加module的顺序如何,compile都会自动根据依赖关系来决定先后的构建关系

2.2 继承 dependencyManagement

继承是用来解决重复依赖的问题

  • 简化配置

  • 减少版本冲突

步骤1:在子工程中的pom.xml中配置<parent>标签

父工程一般为聚合工程,即maven_01_parent,于是在子工程 springmvc_ssm、maven_pojo、maven_dao 中作如下配置

<!-- 配置当前工程继承自parent工程 -->
<parent>
    <groupId>org.example</groupId>
    <artifactId>maven_01_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../maven_01_parent/pom.xml</relativePath>
</parent>

步骤2:优化子项目共有依赖导入问题

将子项目共同使用的jar包都抽取出来,维护在父项目的pom.xml中
删除子项目中被抽取的jar包

<dependencies>
    <!-- mvc相关 -->
    <!-- javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <!-- jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
    </dependency>

    <!-- mybatis相关 -->
    <!-- mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <!-- spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <!-- druid -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!-- mybatis-spring -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>

    <!-- 测试相关 -->
    <!-- spring-test -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

步骤3:优化子项目依赖版本问题

上述设置会导致子项目多出很多不需要的依赖
例如 maven_domain 模块不需要引入任何依赖,但配置父项目后,就包括了父项目中的全部依赖

可以通过<dependencyManagemen>来优化管理,以依赖 junit 为例

  • 在父工程中删除 junit 依赖,同时添加如下依赖管理

    <!-- 定义依赖管理 -->
    <dependencyManagement>
        <dependencies>
            <!-- junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
  • 在需要用到 junit 的子项目中,引入依赖

    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
    

    注意!子项目中引入依赖时不再需要写 version,从而实现统一依赖版本

3. 属性管理

3.1 依赖版本属性管理

需求:希望将所有版本为5.2.10.RELEASE的依赖改为5.1.9.RELEASE

  • 手动修改:每次修改多个,容易遗漏
  • 方案:将版本号抽取为一个参数

步骤1:父工程中定义属性

<!-- 定义属性 -->
<properties>
    <spring.version>5.2.10.RELEASE</spring.version>
    <junit.version>4.12</junit.version>
</properties>

步骤2:修改依赖的version

<!-- spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
</dependency>
<!-- spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>
<!-- spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
</dependency>

3.2 配置文件属性管理(了解)

需求:在之前的springmvc_ssm项目中,有一个jdbc.properties的配置文件,里面定义了driver, url, username, password 这4个属性
现在希望通过maven_01_parent来管理jdbc.properties里面的属性值

步骤1:父工程定义属性

<!-- maven_01_parent中定义属性 -->
<properties>
    ...
    <jdbc.url>jdbc:mysql://localhost:3306/ssm_db?useSSL=false&amp;useServerPrepStmts=true</jdbc.url>
</properties>

步骤2:设置maven过滤文件范围

<!-- maven_01_parent中 -->
<build>
    <resources>
        <resource>
            <!-- Maven在默认情况下是从当前项目的 src\main\resources 下读取文件进行打包
                ${project.basedir}: 当前项目所在目录,子项目继承了父项目,相当于所有的子项目都添加了资源目录的过滤 -->
            <directory>${project.basedir}/src/main/resources</directory>
            <!-- 设置能够解析${},默认是false -->
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
说明:
<directory>../springmvc_ssm/src/main/resources</directory>	只管理springmvc_ssm里面的resources
<directory>${project.basedir}/src/main/resources</directory>	管理所有模块的resources
如果希望只管理某几个子项目,可以写多个<resource>标签

步骤3:jdbc.properties文件中引用属性

# 子模块中
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=123456

刷新maven,可以看到项目结构的变化

步骤4:测试是否生效

install命令将springmvc_ssm打成war包,在本地仓库找到对应的war包
在路径 springmvc_ssm-1.0-SNAPSHOT.war\WEB-INF\classes 中打开生成的jdbc.properties,可以看到 jdbc.url 的值已经被添加
运行项目,正常执行

注意

如果缺乏web.xml文件,打包时可能报错:Error assembling WAR: webxml attribute is required
可以通过将web.xml添加上去解决,也可以通过以下命名忽略web.xml的检查

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.2.3</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
    </plugins>
</build>

3.3 Maven中的属性(了解)

在这里插入图片描述

查看属性:在cmd窗口中输入

mvn help:system	#查看所有属性

在程序中使用某个属性,只需要

${java.runtime.name}

3.4 版本说明

在jar包的版本定义中,有两个工程版本用的比较多:

  • SNAPSHOT(快照版本)
    • 项目开发过程中临时输出的版本,称为快照版本
    • 快照版本会随着开发的进展不断更新
  • RELEASE(发布版本)
    • 项目开发到一定阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的
    • 即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本

此外还经常能看到一些发布版本:

  • alpha版:内测版,bug多不稳定内部版本不断添加新功能
  • beta版:公测版,不稳定(比alpha稳定些),bug相对较多不断添加新功能
  • 纯数字版

4. 多环境配置与应用

4.1 多环境开发

在这里插入图片描述

在maven_01_parent里面配置多环境
需要删除之前在属性里配置的jdbc.url,然后再加入以下配置

<!-- 配置多环境 -->
<profiles>
    <!-- 1. 开发环境 -->
    <profile>
        <id>env_dep</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db?useSSL=false&amp;useServerPrepStmts=true</jdbc.url>
        </properties>
        <!-- 设定是否为默认启动的环境 -->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <!-- 2. 生产环境 -->
    <profile>
        <id>env_pro</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.2.2.1:3306/ssm_db?useSSL=false&amp;useServerPrepStmts=true</jdbc.url>
        </properties>
    </profile>
    <!-- 3. 测试环境 -->
    <profile>
        <id>env_test</id>
        <properties>
            <jdbc.url>jdbc:mysql://127.3.3.1:3306/ssm_db?useSSL=false&amp;useServerPrepStmts=true</jdbc.url>
        </properties>
    </profile>
</profiles>

上述设定默认的启动环境是开发环境

也可以通过以下命令动态指定环境

mvn install -P env_test

在这里插入图片描述

4.2 跳过测试

如果在测试环境使用install,那么所有的test都将依次执行
当部分模块还没有开发完毕,但需要对已经开发完毕的打包时,就无法完成。此时需要跳过测试

应用场景

  • 功能更新中并且没有开发完毕
  • 快速打包

方法一:IDEA工具实现跳过测试

在这里插入图片描述

此时执行install,由于跳过了测试,程序里的 BookServiceTest 不会被执行

  • 一次性跳过全部测试

方法二:配置插件实现跳过测试

<build>
    <plugins>
        <plugin>
            <!-- 内部插件,无需提供groupId -->
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.12.4</version>
            <configuration>
                <!-- skipTests设置成true 直接跳过所有测试 -->
                <skipTests>false</skipTests>
                <!-- 排除掉不参与测试的内容,如BookServiceTest -->
                <excludes>
                    <exclude>**/BookServiceTest.java</exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

方法三:命令行跳过测试

mvn package -D skipTests

在这里插入图片描述

注意:cmd要在pom.xml所在目录下进行执行

5. 私服

A,B,C合作开发项目,如果B想要使用A开发的模块,就需要用到私服

  • 中央仓库不允许私人上次jar包
  • 可以搭建一个类似中央仓库的私服,A将自己开发的模块上传到私服,B只需要联网下载即可使用

私服:公司内部搭建的用于存储Maven资源的服务器

远程仓库/中央仓库:Maven开发团队维护的用于存储Maven资源的服务器

  • 私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题
  • 搭建Maven私服的方式很多,一种常见的方式是通过 Nexus

5.1 私服安装

步骤1:下载和解压nexus

  • 官网下载(慢)

    下载地址:https://help.sonatype.com/repomanager3/download)

    在这里插入图片描述

  • 百度云盘下载

    链接:https://pan.baidu.com/s/1nFgGeDtSL-e0np3BpB7YRQ
    提取码:ar7m

  • 安装

    下载后解压即可安装完毕
    在这里插入图片描述

  • 说明

    nexus文件夹中的nexus.vmoptions中定义了sonatyoe-work的地址,用到了后者的一些配置,因此这两个文件夹都需要保留
    在这里插入图片描述

步骤2:启动nexus

在这里插入图片描述

在bin目录下打开cmd,执行

nexus.exe /run nexus

即可启动
在这里插入图片描述

步骤3:访问nexus服务器

访问 http://localhost:8081
首次使用需要点击 sign up,根据提示到指定位置找到密码,然后登录

在这里插入图片描述

登录成功后,根据提示进行设置

在这里插入图片描述

报错问题

这里登录之后可能会报一个:java.net.UnknownHostException: sonatype-download.global.ssl.fastly.net
导致结果:能正常使用nexus基础功能,但无法正常关闭
可能的原因:官网进不去导致的
暂时的解决方法:关闭拓展

在这里插入图片描述

步骤4:关闭nexus

关闭这里常无法关闭,建议先关闭页面,再关闭nexus

  • 方法一:ctrl+c

  • 方法二:命令行

    在nexus.exe路径下另启一个cmd窗口,输入以下命令

    nexus.exe /stop nexus
    
  • 方法三:点 x 强制关闭(不推荐)

步骤5: 修改配置

  • 修改基础配置信息
    • 安装路径下etc目录中nexus-default.properties文件保存有nexus基础配置信息,例如默认访问端口
  • 修改服务器运行配置信息
    • 安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应的配置信息,例如默认占用内存空间

5.2 私服中的仓库分类

在这里插入图片描述

私服里有多个仓库,这些仓库分为三大类

  • 宿主仓库hosted

    保存无法从中央仓库获取的资源

    • 自主研发
    • 第三方非开源项目,比如Oracle,因为是付费产品,所以中央仓库没有
  • 代理仓库proxy

    每次去中央仓库下载,速度慢,代理仓库可用于专门存储从远程中央仓库下载的第三方jar包

    • 代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库
  • 仓库组group

    私服里有宿主仓库,有存放SNAPSHOT的代理仓库,有存放RELEASE类型的代理仓库……
    为了设置获取资源时在哪个仓库中获取,可以将所有的仓库编成一个组,只需要访问仓库组去获取资源

    • 将若干个仓库组成一个群组,简化配置
    • 仓库组不能保存资源,属于设计型仓库

在这里插入图片描述

之前的web项目,实际上用的是阿里云私服

5.3 本地仓库访问私服配置

步骤1:私服上配置仓库

  • 需求:创建两个仓库:personal-snapshot 和 personal-release

创建新的仓库

在这里插入图片描述

仓库类型选择maven2 (hosted),设置仓库名称和存储的jar包类型

在这里插入图片描述

创建好personal-snapshot后,同样的方式再创建一个personal-release,只将Version policy改为Release即可

在这里插入图片描述

步骤2:配置本地仓库对私服的访问权限

在这里插入图片描述

在配置文件setting.xml中配置<servers>

<servers>
	<!-- 配置访问私服personal_snapshot的权限 -->
	<server>
      <id>personal-snapshot</id>
      <username>admin</username>
      <password>123456</password>
    </server>
    <!-- 配置访问私服personal_release的权限 -->
	<server>
      <id>personal-release</id>
      <username>admin</username>
      <password>123456</password>
    </server>
</servers>
  • id:私服中仓库的名称

步骤3:配置私服的访问路径

  1. 在配置访问路径前,需要先将前面新创建的仓库加入到仓库组中,使仓库组能够管理它们

在这里插入图片描述

  1. 进入maven-public仓库组,添加仓库

在这里插入图片描述

  1. 在配置文件setting.xml中配置<mirrors>
<mirrors>
    <!-- 配置私服的访问路径 -->
	<mirror>
		<id>maven-public</id>
		<mirrorOf>*</mirrorOf> <!-- *表示所有jar包都通过私服获取 -->
		<url>http://localhost:8081/repository/maven-public/</url>
	</mirror>
    <!-- 之前使用的是阿里云私服,这里将其注释掉
	<mirror>
		<id>alimaven</id>
		<name>aliyun.maven</name>
		<url>https://maven.aliyun.com/repository/public</url>
		<mirrorOf>central</mirrorOf>
	</mirror>
	-->
</mirrors>

5.4 私服资源上传和下载

步骤1:在项目maven-01-parent的pom.xml中配置

<!-- 配置当前工程保存在私服中的具体位置 -->
<distributionManagement>
    <repository>
        <id>personal-release</id>
        <url>http://localhost:8081/repository/personal-release/</url>
    </repository>
    <snapshotRepository>
        <id>personal-snapshot</id>
        <url>http://localhost:8081/repository/personal-snapshot/</url>
    </snapshotRepository>
</distributionManagement>

要发布的项目都需要配置distributionManagement标签,要么在自己的pom.xml中配置,要么在其父项目中配置,然后子项目中继承父项目即可

步骤2:deploy 上传到私服

在这里插入图片描述

注意,此时已经更改为从私服获取jar,当第一次上传时,由于私服的代理仓库maven-central为空,必然花费一定时间去下载 maven-01-parent 里面用到的所有jar包到私服中去

步骤3:查看私服中仓库 personal-release 和 personal-snapshot

在这里插入图片描述

可以看到personal-snapshot里面已经有上传的项目了,然而personal-release里面依然为空
这是因为maven_01_parent的pom.xml里面设置了当前项目为<version>1.0-SNAPSHOT</version>

<groupId>org.example</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

如果将其改为<version>1.0-RELEASE</version>,即可上传到仓库personal-release里面去
注意:子工程也要修改为RELEASE,否则子项目会被发布到personal-snapshot当中去

步骤4(非必要):配置私服去阿里云中下载依赖

如果私服中没有对应的jar,会去中央仓库下载,如果速度可能太慢,可以配置让私服去阿里云中下载依赖

在这里插入图片描述

如果需要修改,可改为:https://maven.aliyun.com/repository/public

下载资源同之前一样,直接在pom.xml里面引入坐标即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值