赞
踩
maven本质是一个项目管理工具,将项目开发和管理过程抽象为一个项目对象模型(POM)
为什么要学习maven?
Maven 可以帮助我们构建项目、依赖管理。
原因1,在团队开发流程中:
从代码托管中心 git,把完整功能宕下来。再部署到linux服务器,但是该服务器里面一定不会安装idea。这个时候,就要借助于专门的构建工具maven来构建。
原因2,maven的依赖管理:
一个模块用到上百个jar包是非常正常的。非常的浪费磁盘空间。maven可以非常方便你的帮我们管理我们的jar包。
maven官网:Maven – Welcome to Apache Maven
核心程序压缩包:apache-maven-3.5.4-bin.zip,如下图解压即安装
要下载指定的版本:Index of /dist/maven/maven-3 (apache.org)
如下,点击binaries
选择zip文件,下载即可
1.检查JAVA_HOME配置是否正确
Maven是一个用Java语言开发的程序,它必须基于JDK来运行,需要通过JAVA_HOME来找到JDK的安装位置。
或者也可以使用cmd命令查看JAVA_HOME环境变量
可以用 win+R,cmd进入小黑板,输入java -version回车来查看,有下面这样的效果就说明 JAVA_HOME配置好了
2.配置MAVEN_HOME
配置MAVEN_HOME环境变量
3.配置PATH
配置环境变量的规律:
XXX_HOME指向的是bin目录的上一级
PATH指向的是bin目录
4.验证MAVEN_HOME配置是否正确
可以用 win+R,cmd进入小黑板,输入mvn -v回车来查看,有下面这样的效果就说明 MAVEN_HOME配置好了
本地仓库默认值
查看用户家目录,输入并回车,会自动跳转到用户家目录
本地仓库默认值:用户家目录/.m2/repository。
自定义maven的本地仓库
本地仓库这个目录,我们手动创建一个空的目录即可。建议将Maven的本地仓库放在其他盘符下。配置方式如下:
编辑Maven的核心配置文件:conf/settings.xml
本地仓库的东西从哪来呢?就需要配置阿里云提供的镜像仓库
maven下载jar包默认访问境外的中央仓库,速度很慢。改成阿里云提供的镜像仓库,访问国内网站,可以让maven下载jar包的时候速度更快。配置的方式是:将下面mirror标签整体复制到mirrors标签的内部。
使用阿里云旧版maven仓库
- <mirrors>
- <mirror>
- <id>nexus-aliyun</id>
- <mirrorOf>central</mirrorOf>
- <name>Nexus aliyun</name>
- <url>http://maven.aliyun.com/nexus/content/groups/public</url>
- </mirror>
- </mirrors>
使用阿里云新版maven仓库
- <mirror>
- <id>nexus-aliyun</id>
- <mirrorOf>central</mirrorOf>
- <name>Nexus aliyun</name>
- <url>https://maven.aliyun.com/repository/public</url>
- </mirror>
配置maven工程的基础jdk版本
如果按照默认配置运行,Java工程使用的JDK版本是1.5。配置的方式是:将profile标签整个复制到profiles标签内。
<profiles> <profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile> </profiles>
可以直接通过mvn archetype:generate来创建项目。
mvn archetype:generate
在创建的过程中,我们需要填写项目的package和项目名称以及项目的版本
mvn archetype:generate -DgroupId=com.xiaoyumao -DartifactId=demo-project -Dpackage=com.xiaoyumao -Dversion=1.0-SNAPSHOT -DarchetypeCatalog=internal
使用idea创建maven项目
1、idea 配置好maven
2、idea右上角点击
进入后,选择moudles-new moudle
选择maven-点击 next【没有使用骨架创建,不勾选create from archetype】
填写gav坐标后,点击next
再点击finish
---
创建后,发现都是灰色的。。
可以点击上方的那些按钮,进行对应颜色的修改
使用JBLJavaToWeb创建maven的web工程
先用上面的方式创建一个普通的maven工程,maven-web-project
然后:如下
在工程上右键,选择JBLJavaToWeb,即可以把一个普通的maven工程转为web的maven工程
效果:在src\main下生成webapp目录,pom文件打包方式变为war
点+
选择tomcat server
点击加号,加入maven-web:war exploded
Maven为了让构建过程能够尽可能自动化完成,所以必须约定一个目录结构。例如:Maven执行编译操作,必须先去Java源程序目录读取Java源代码,然后执行编译,最后把编译结果存放在target目录。
约定大于配置
Maven对于目录结构这个问题,没有采用配置的方式,而是基于约定。这样会让我们在开发过程中非常方便。如果每次创建Maven工程后,还需要针对各个目录的位置进行详细的配置,那肯定非常麻烦。
目前开发领域的技术发展趋势就是:配置大于编码,约定大于配置。
src的同层目录,创建pom.xml
modelVersion标签,从maven2开始固定就是4.0.0,代表当前pom.xml所采用的标签结构
<modelVersion>4.0.0</modelVersion>
packaging标签,表示打包方式
<packaging>jar</packaging>
maven的坐标用于描述藏书种资源的位置
maven仓库:https://mvnrepository.com/
gav坐标和仓库中jar包的存储路径之间的对应关系
坐标:
<groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version>上面坐标对应的jar包在Maven本地仓库中的位置:
Maven本地仓库根目录\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar
Java项目开发过程中,构建指的是使用『原材料生产产品』的过程。
原材料:Java源代码、基于HTML的Thymeleaf文件、图片、配置文件...
产品:一个可以在服务器上运行的项目(指web应用)
构建是一个过程。构建过程包含的主要的环节:
这里打包、安装、部署的意思呢?
maven工程(打jar包的maven工程)执行package打包,打包后就跟我们用的第三方jar包一模一样;
install安装后,让war包去依赖install后的jar包,其实就是Web工程里导入的jar包。放在Web工程的WEB-INF/lib目录下,最后让war包部署到服务器运行。
要牢记:构建的最终产品就是war包
打包的结果会存放在target目录下
jar包的名字是 artifactId-version.jar
进入pom.xml所在的目录,使用cmd命令进入命令行窗口
命令:mvn compile
编译完成之后,会多一个target目录
命令:mvn package
命令:mvn install
把打包的东西放到本地仓库目录
1、双击compile,会在src同级生成target目录
2、双击test
配置运行环境
1、
2、
具体干活都是maven插件完成的。
一个插件可以有多个目标(即多个功能),而每一个目标都和生命周期的某一个环节对应。如下,
依赖:指当前项目运行所需的jar,一个项目可以设置多个依赖
jar包统一的下载来源:maven会统一去中央仓库下载。
maven仓库:https://mvnrepository.com/
也可以设置一个镜像,比如阿里云镜像网站下载。
- <mirror>
- <id>alimaven</id>
- <mirrorOf>central</mirrorOf>
- <name>aliyun maven</name>
- <url>http://maven.aliyun.com/nexus/content/groups/public</url>
- </mirror>
情况一jar包没有下载完
1.clearLastUpdated.bat工具(把文件中路径改掉,改成自己的本地maven仓库的地址)
文件内容如下:
cls @ECHO OFF SET CLEAR_PATH=D: SET CLEAR_DIR=D:\maven-rep220328 color 0a TITLE ClearLastUpdated For Windows GOTO MENU :MENU CLS ECHO. ECHO. * * * * ClearLastUpdated For Windows * * * * ECHO. * * ECHO. * 1 清理*.lastUpdated * ECHO. * * ECHO. * 2 查看*.lastUpdated * ECHO. * * ECHO. * 3 退 出 * ECHO. * * ECHO. * * * * * * * * * * * * * * * * * * * * * * * * ECHO. ECHO.请输入选择项目的序号: set /p ID= IF "%id%"=="1" GOTO cmd1 IF "%id%"=="2" GOTO cmd2 IF "%id%"=="3" EXIT PAUSE :cmd1 ECHO. 开始清理 %CLEAR_PATH% cd %CLEAR_DIR% for /r %%i in (*.lastUpdated) do del %%i ECHO.OK PAUSE GOTO MENU :cmd2 ECHO. 查看*.lastUpdated文件 %CLEAR_PATH% cd %CLEAR_DIR% for /r %%i in (*.lastUpdated) do echo %%i ECHO.OK PAUSE GOTO MENU
情况二:下载完了但是内容不完全,如报错方法不存在,类不存在
使用文件校验工具,比较俩个值是否相等就可以判断是否丢包了,建议删了重新下载改jar包
Could not find artifact XXX
1.刷新maven项目
Generate Sources and update folders for all projects
2. maven clean install
在不同的位置是否能够使用这个jar,从空间、时间俩个角度来看:
- compile,不设置依赖范围默认则compile编译范围
- test,测试范围。在主程序和服务器不能用。在开发时的测试程序中可以使用,如junit, 因为最终打成的jar包没有测试程序
- provided:被服务器提供(不会被部署在服务器),如jsp-api,servlet-api,由tomcat提供。
只有默认范围complie范围的jar才可以传递。
测试依赖的传递性:
在maven-A工程里引入三种不同依赖范围的依赖,简写如下:
简写如下: <dependency> <artifactId>servlet-api</artifactId> <scope>provided</scope> </dependency> <dependency> <artifactId>druid</artifactId> </dependency> <dependency> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
在maven-web工程里引入maven-A工程的依赖
<dependency> <groupId>com.atguigu.maven</groupId> <artifactId>maven-A</artifactId> <version>1.0-SNAPSHOT</version> </dependency>效果如下:只有默认范围complie范围的jar才可以传递依赖给maven-web工程。
依赖排除指主动断开依赖的资源,被排除的依赖不需要指定版本号,只需要设置groupId和artifactId
- <dependency>
- <groupId>com.atguigu.maven</groupId>
- <artifactId>maven-A</artifactId>
- <version>1.0-SNAPSHOT</version>
- <!--依赖排除-->
- <exclusions>
- <exclusion>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
依赖排除后效果如下:
可选依赖是私房钱,控制别人能不能看到
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <optional>true</optional>
- </dependency>
optional表示是否会传递依赖,有两个可填值(假如不声明optional标签,默认就是false):
在命令行中,进入项目所在的目录,运行以下命令:
---- 列出项目的所有jar包
mvn dependency:list
执行结果
mvn dependency:list -Dverbose
该命令可以列出项目依赖的所有jar包,-Dverbose参数会把被忽略的jar,即相同jar包的不同版本引入也列出来。
---- 列出项目的包依赖树
mvn dependency:tree
这个命令跟上一个list命令的区别就是,这个命令的依赖,输出来是个树,更方便看依赖关系。
执行结果
dependency:tree
有几个比较重要的参数,非常有用:
- includes
- 说明:该参数可以列出指定要求的jar,其他的忽略
- 示例:
-Dincludes=velocity:velocity
,只列出velocity的依赖关系- 参数值:
[groupId]:[artifactId]:[type]:[version]
,参数格式就是这样的,没有的值可以留空,举例-Dincludes=:spring-aop
,-Dincludes=:::5.0.6.RELEASE
,-Dincludes=org.springframework
- 通配符:在参数中可以使用通配符,例如
org.apache.*
,:::*-SNAPSHOT
- 多个参数值:参数后面可以跟多个参数值,以英文逗号分隔,举例
-Dincludes=org.apache.maven*,org.codehaus.plexus
- excludes
- 说明:该参数的用法跟
includes
是一样的,不过这个参数的作用是排除指定的jar
包发生冲突后maven默认的使用规则:
路径最短者优先,路径相同者,先配置者优先
比如我们查看一下commons-collections
包的冲突
命令:mvn dependency:tree -Dverbose -Dincludes=commons-collections
输出:
- [INFO] [dependency:tree]
- [INFO] org.apache.maven.plugins:maven-dependency-plugin:maven-plugin:2.0-alpha-5-SNAPSHOT
- [INFO] +- org.apache.maven.reporting:maven-reporting-impl:jar:2.0.4:compile
- [INFO] | \- commons-validator:commons-validator:jar:1.2.0:compile
- [INFO] | \- commons-digester:commons-digester:jar:1.6:compile
- [INFO] | \- (commons-collections:commons-collections:jar:2.1:compile - omitted for conflict with 2.0)
- [INFO] \- org.apache.maven.doxia:doxia-site-renderer:jar:1.0-alpha-8:compile
- [INFO] \- org.codehaus.plexus:plexus-velocity:jar:1.1.3:compile
- [INFO] \- commons-collections:commons-collections:jar:2.0:compile
我们可以看到,2.1版本的jar被忽略掉了,因为maven是根据路径最近原则来解析依赖,2.0版本路径更短,所以2.0版本被引入,2.1版本路径比2.0要长,所以被忽略。
使用这个命令可以轻松的查看包的引入路径,包的冲突情况。
此处一定不要省略-Dverbose
参数,要不然是不会显示被忽略的包
示例:查找某一个jar包是通过哪个maven坐标引入的。
举例:发现这一个类出现了同名同包的情况,
就想看看angus-mail-1.0.0.jar是通过哪个坐标引入的
maven命令:mvn dependency:tree -Dverbose -Dincludes=org.eclipse.angus:angus-mail
dependency:tree 表示树状显示,还可以dependency:list
-Dverbose 表示可以显示所有的引用,包括因为多次引用重复而忽略的。。
-Dincludes 可以制定查询条件
做下依赖排除
- <dependency>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-rt-frontend-simple</artifactId>
- <version>4.0.3</version>
- <!--依赖排除-->
- <exclusions>
- <exclusion>
- <groupId>org.eclipse.angus</groupId>
- <artifactId>angus-mail</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
方式一:使用mvn命令将jar放入maven库,然后进行依赖打包。
方式二:将jar包放入项目中与src同级
需要在pom.xml文件加入jar包依赖。
- <properties>
- <parent.basedir>F:\GitProject\rpa-app\rpa-client</parent.basedir>
- </properties>
-
- <!-- 引入非maven的第三依赖 start -->
- <dependency>
- <groupId>com.spasvo</groupId>
- <artifactId>spasvo-websocket</artifactId>
- <version>1.0</version>
- <scope>system</scope>
- <systemPath>${parent.basedir}/lib/spasvo-websocket.jar</systemPath>
- </dependency>
- <dependency>
- <groupId>com.spasvo</groupId>
- <artifactId>Tess4J</artifactId>
- <version>1.0</version>
- <scope>system</scope>
- <systemPath>${parent.basedir}/lib/Tess4J.jar</systemPath>
- </dependency>
什么叫聚合:对父工程的所有操作子工程也会跟着做相同的操作(比如清理、编译、打包)
父工程会使用modules标签自动聚合,且打包方式设置为pom
在maven-A工程上右键,创建新模块maven-son
子工程maven-son会自动创建到父工程maven-A下
创建后父工程多了一个标签<modules>且自动把父工程打包方式设置为pom
<groupId>com.atguigu</groupId> <artifactId>maven-A</artifactId> <!--maven的打包方式--> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <!--聚合--> <modules> <module>maven-son</module> </modules>在子工程的pom文件中也自动多了一个<parent>标签,指定当前工程的父工程
<!-- 使用parent标签指定当前工程的父工程 --> <parent> <artifactId>maven-A</artifactId> <groupId>com.atguigu</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <!-- 子工程的坐标 --> <!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 --> <groupId>com.atguigu</groupId> <artifactId>maven-son</artifactId>如何指定父工程的位置呢
maven工程继承的本质是子工程的pom.xml中的配置继承了父工程pom.xml的配置,这样就可在父工程中统一管理项目中的依赖信息的版本
从继承关系角度来看:
- 父工程maven-A
- 子工程maven-son
这样让maven工程继承的好处是什么呢
父工程会无条件把所依赖的所有jar包都继承给子工程【dependencies】
此时可以把任何依赖范围的jar都传下去。
如下图:子工程maven_son的pom文件里啥都没写呢,就把父工程maven-A中的三种依赖范围的依赖都继承了!
问题就来了,作为子工程有时候我用不着的依赖也给我继承了下来。怎么办呢
让父工程管理依赖,被管理的依赖并没有真正被引入到父工程。
把父工程maven-A中的依赖用 <dependencyManagement>包起来。
这时候,子工程maven_son的依赖长就这样了。没有任何依赖被他继承到
父工程maven-A管理依赖的好处是什么呢?:
子工程maven_son可以选择性的继承父过程给的依赖,且依赖范围和版本号就可以不用写了,表示这个依赖的版本使用父工程控制。要是写了,那就用子工程自己的
- <dependencies>
- <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- </dependency>
-
- </dependencies>
此时虽然父工程中有3个依赖,但是子工程只选择性的继承了其中的俩个
父工程中使用dependencyManagement和dependencies的区别
dependencyManagement:依赖管理
为了管理依赖版本
子工程还需要自己引入依赖,但是不用指定版本号dependencies:依赖引入
子工程直接继承得到依赖不需要引入
父工程中自定义属性来管理jar包的版本
- <!-- 通过自定义属性,统一指定Spring的版本 -->
- <properties>
- <spring.version>5.3.1</spring.version>
- <properties/>
比如spring系列jar包有很多个,设置版本号时就可以这么使用,修改版本号的时候就可以一键修改了,真正实现“一处修改,处处生效”。
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>${spring.version}</version>
- </dependency>
维护依赖也只能维护版本号,scope也能不改就别改,
查看可用的系统属性和环境变量属性
mvn help:system
系统属性
调用格式,如${user.home}
环境变量属性
调用格式,如${env.JAVA_HOME}
1、pom中配置属性值
定义自定义属性
- <properties>
- <spring.version>5.1.9.RELEASE</spring.version>
- <junit.version>4.12</junit.version>
- 在构建过程中,读取源码使用的字符集
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
2、在build里说明参与构建
路径还可以改
3、资源目录下的资源文件jdbc.properties就可以使用了
创建多环境
使用,在install时指定使用哪一个环境
指定默认环境
这样一种场景,需要把某一个jar包(如:ojdbc6-11.2.0.3.jar)放到maven仓库中,然后才可以在pom中进行配置。
注:Oracle官方宣布的Oracle数据库11g的驱动jar包是ojdbc6.jar
安装jar到本地maven库
下载ojdbc6.jar文件后,将其放到比较好找的目录下,比如D盘根目录
进入maven的bin里面,在bin里面打开cmd窗口
执行maven命令:
mvn install:install-file -Dfile=D:/ojdbc6-11.2.0.3.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.3 -Dpackaging=jar
---------------------------------------------
mvn install:install-file:主要是将本地自定义jar安装到maven仓库,然后在pom中可以直接通过dependency的方式来引用。
<dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </dependency>这里的groupid就是你之前安装时指定的-Dgroupid的值,artifactid就是你安装时指定的-Dartifactid的值,version也一样。
-------------------------------------
mvn install:install-file:此命令有如参数:
命令 说明
-DgroupId=自定义groupId 设置groupId 名
-DartifactId=自定义artifactId 设置该包artifactId名
-Dversion=自定义版本 设置版本号
-Dpackaging=jar 设置该包的类型,有如下值:pom、jar、war、maven-plugin。但是一般常用的是jar类型
-Dfile=文件路径 设置该jar包文件所在的路径与文件名
扩展:
如果本地有多个maven仓库,如何用mvn install命令安装jar包到指定的仓库?
Dmaven.repo.local是指定的maven仓库的地址
查看maven配置的仓库地址,可在conf文件夹下的settings.xml文件中查看
创建项目,注意命名规范
指定打包方式:maven-plugin
<packaging>maven-plugin</packaging>
引入依赖:使用文档注释方式
<dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>3.5.2</version> </dependency>创建Mojo类,需要继承AbstractMojo
/** * @goal sayHello */ public class MyHelloPlugin extends AbstractMojo { @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("hello maven plugin"); } }
安装插件
插件注册:
将插件的groupId注册到settings.xml中
使用插件:maven可以根据插件的artifactId自动识别插件前缀,如maven-hello-plugin,就可以识别到前缀为hello
找一个别的maven工程,在idea中右键pom.xml选择Open in Terminal
成功
maven插件与生命周期的阶段绑定,在执行到对应生命周期时执行对应的插件功能。
作用:干预默认的构建过程
构建过程指定maven版本
或者还可以这么指定
<properties> <maven.complier.source>1.8</maven.complier.source> <maven.complier.target>1.8</maven.complier.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
spring-boot-maven-plugin
在SpringBoot项目中,经常会发现pom.xml会有spring-boot-maven-plugin插件
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>一般的maven项目的打包命令,不会把依赖的jar包也打包进去的,只是会放在jar包的同目录下,能够引用就可以了。
但是spring-boot-maven-plugin插件,会将依赖的jar包全部打包进去。该文件包含了所有的依赖和资源文件,可以直接在命令行或者传统的 Java Web 服务器上启动运行。
---------------------------
前面说了,如果使用该插件,那么打出来的包是一个可执行的jar包,这样的jar包,在被别的项目引用的时候,可能会出问题。那如何打成一个普通的jar包。
当然你可以把这个插件注释掉,重新打包或者如下:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin>
dockerfile-maven-plugin
需要将应用部署到容器平台,在打包时生成docker镜像。pom配置如下:
<properties> <dockerfile-version>1.4.9</dockerfile-version> </properties> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>${dockerfile-version}</version> <configuration> <repository>${project.build.finalName}</repository> <tag>${project.version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> <executions> <execution> <id>default</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin> </plugins>制作Dockerfile
- <build>
- <!-- 项目的名字 -->
- <finalName>WebMavenDemo</finalName>
- <!-- 描述项目中资源的位置 -->
- <resources>
- <!-- 自定义资源1 -->
- <resource>
- <!-- 资源目录 -->
- <directory>src/main/java</directory>
- <!-- 包括哪些文件参与打包 -->
- <includes>
- <include>**/*.xml</include>
- </includes>
- <!-- 排除哪些文件不参与打包 -->
- <excludes>
- <exclude>**/*.txt</exclude>
- <exclude>**/*.doc</exclude>
- </excludes>
- </resource>
- </resources>
- </build>
1、Error:(51,44) java: 编码GBK的不可映射字符
找到报错的文件、改变文件的编码格式
2、Error:(6,19) java: 东西明明在,怎么就是依赖不了呢
加入模块依赖,勾选
shishi
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。