文章目录
- Maven
- 安装Maven
- Maven的工作流程
- 配置Maven
- Maven的使用
- module和project的关系
- 如何用Maven导包
- 如何用Maven进行项目构建
- 指令介绍
- clean指令
- compile指令
- package指令
- install指令
- Maven的依赖管理
- 如何导包
- scope作用域
- 依赖传递
- 依赖冲突
- 使用Maven开发项目
- Junit
- 如何使用Junit
Maven
- Maven是一个项目管理工具,主要有两个功能:
- 项目构建
- 指可以帮助我们编译项目、打包项目(可以帮助我们把自己的项目打包成一个
.jar
文件)、安装项目、部署项目
- 指可以帮助我们编译项目、打包项目(可以帮助我们把自己的项目打包成一个
- 依赖管理
- 当我们的项目变得复杂之后,项目中的依赖越来越多,管理起来也越来越复杂,Maven可以帮助我们去管理这些依赖。
- 项目构建
安装Maven
版本说明:
- JDK:
1.8
- Maven:https://maven.apache.org/download.cgi(不要下最新版本)
解压:
- 证明安装成功
配置环境变量:
- 打开高级系统设置,配置系统变量
- 配置环境变量
最后在cmd中输入mvn -v,查看当前版本
Maven的工作流程
传统写代码的问题:
jar
包反复存储,占用空间- 手动管理,容易混乱
Maven的工作流程图:
- 本地仓库:其实就是本地存放Jar包的一个路径,统一的集中式的去管理本地的所有jar包
- 中央仓库:中央仓库其实就是Maven 提供的一个仓库,里面收录了世界上所有的开源的jar包,但是在国外,网速慢。
- 镜像仓库:阿里等公司会去定期同步中央仓库,把中央仓库的内容同步过来。这样我们后续在下载jar包的时候,就可以让他指定去镜像仓库下载,这样下载的速度就会比较快。
配置Maven
- 配置settings.xml
- 在
conf
文件里 - 配置本地仓库的路径
- 配置镜像仓库
- 配置JDK的编译版本
- 在
源码:
<settings>
...
<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>
...
</settings>
-------------------------------------------------------------------------------------
<settings>
...
<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>
...
</settings>
- 配置idea
- 在Settings中搜索Maven
- Other Settings —> Settings for New Projects —> Maven
- 在Settings中搜索Maven
Maven的使用
Maven工程的要求:
-
在项目的根路径下,有一个
pom.xml
文件 -
工程目录是如下的结构:
-
ProjectName
- src(src里面不直接写包)
- main
- java(写代码的地方,指源代码的路径)
- resources(配置文件地方,指配置文件的路径)
- test
- java(单元测试代码,指测试类的存放路径)
- resources(单元测试的配置文件,指测试类需要用到的文件)
- main
- src(src里面不直接写包)
-
pom.xml(在项目的根目录下)
eg:
怎么把一个项目转换成maven项目:
- 在
src
里面建几个包src/main/java
- mark as sources
src/main/resources
- mark as resources
src/test/java
src/test/resources
- 创建一个
pom.xml
- 对着
pom.xml
点击add as maven project
怎么通过idea创建一个Maven项目:
- GroupId:指公司名、组织名
- eg:
com.coo1heisenberg
- eg:
- ArtifactId:项目名
- eg:
test_maven
- eg:
module和project的关系
-
project
一个项目是IDEA开发工作的顶级组织单位。在其完成的形式中,一个项目可能代表一个完整的软件解决方案
项目是以下内容的集合:- 工作成果:源代码、脚本、配置文件、文档、包等。
- 用于开发、编译、运行和测试代码的SDK和库。
- 在项目上下文中表示你的工作偏好设置
- 一个项目有一个或者多个模块作为其部件
-
module
- 模块是项目的一部分,你可以独立的编译、运行、测试和调试。
- 模块是一种在维护公共项目配置的同事降低大型项目复杂性的方法。
- 模块可以重复使用:如果需要,可以再多个项目中包含一个模块。
如何用Maven导包
- 打开https://mvnrepository.com/。搜索要用的包,找到指定的版本
- 拷贝坐标
groupId
、artifactId
、version
叫做坐标,可以唯一确定一个包
- 只需要在
pom.xml
文件中声明jar
包的坐标就可以了,添加了之后点击import changes
eg:
如何用Maven进行项目构建
指令介绍
项目构建其实就是 Maven可以帮助我们去检查项目,编译项目,测试项目,打包项目,安装项目,部署项目
clean指令
Maven指令的执行依赖于一些jar
包
- 方式一:通过
cmd
执行
- 方式二:通过idea自带的命令行执行
- 得以管理员身份打开idea,否则识别不出
mvn
命令
- 得以管理员身份打开idea,否则识别不出
- 方式三:直接使用maven的可视化插件(常用)
compile指令
- compile是编译的意思,可以帮助我们生成一个
target文件夹
- 以后,只能在java文件夹中写代码,在resources文件夹里面,写配置文件
- 在
src/main/java
中的代码,会编译到target/classes
里面 - 在
src/main/java
中的配置文件、其他文件,不会进入到target/classes
里面 - 在
src/main/resources
中的代码,会拷贝到target/classes
里面
- 在
test
文件是运行单元测试的,只会运行test
文件里面java
的单元测试- 先引入
Maven
中的Junit
Assert.assertEquals()
:在单元测试里面,使用Assert
断言帮我们完成自动化的检验工作
- 先引入
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
package指令
package可以帮助我们把项目打包
- 打包的名字:
artifactId-version.jar
(是artifactId
加上文件的版本) - 打包的格式:
-
jar
- 默认的打包格式
-
war
- 需要指定
- 指定的格式为:
-
<!-- 指定打包的格式,默认为jar ,可以配置为 war 和 pom -->
<packaging>jar</packaging>
install指令
- install命令可以帮助我们把package生成的jar包复制到本地仓库中
- 需要掌握根据
groupId
、artifactId
、version
找本地的jar
eg:
Maven的依赖管理
如何导包
按照上面说到的三步流程执行即可
scope作用域
每个依赖包都有自己作用范围
<scope>XXX</scope>
eg:
- test
- 仅仅在测试包(
src/test/java
)路径下有效,在src/main/java
路径下失效。
- 仅仅在测试包(
- provided
- 在编译的时候生效,在运行的时候失效
- runtime
- 在编译的时候失效,在运行的时候生效
- 最常见的是:数据库的驱动包
- 设计原因:就是防止写代码的时候,用了MySQL特有的类,切数据库的时候不好操作
- compile
- 默认的作用域
- 在编译和运行的时候都生效
依赖传递
- 指依赖具有传递性
- eg:引入了
commons-dbcp
,而commons-dbcp
又引入了commons-pool
依赖冲突
- 当在同一个项目中,导入同一个依赖的不同的版本,就会有冲突的问题。
- 如何解决依赖冲突
- 声明优先原则
- 是指这同一个项目的不同的版本的jar包,声明优先仅仅指的是第二级后面的依赖,谁先在
pom.xml
中声明,以谁为准 - 如果在
pom.xml
里,同时依赖了两个版本。是以最后一个指定的为准
- 是指这同一个项目的不同的版本的jar包,声明优先仅仅指的是第二级后面的依赖,谁先在
- 就近原则
- 在进行依赖传递的时候,谁传递的次数比较少,以谁为准
- 就近原则的优先级高于声明优先原则
- 手动排除
- 手动去排除传递过来的依赖
- 声明优先原则
eg:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.13</version>
</dependency>
其中:
spring-context依赖了spring-beans(5.3.22) 优先!!!
spring-jdbc依赖了spring-beans(5.3.13)
--------------------------------------------------
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.22</version>
</dependency>(优先!!!)
--------------------------------------------------
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.4</version>
<!-- 手动排除 -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
- 提取常量
- 这个是一个避免依赖冲突的方法。是后面工作中主要推荐的做法。
- 常量名字不要随便取
eg:
<properties>
<!--
1. 提取了常量之后,可以避免依赖冲突的问题
2. 提取了常量之后,可以方便我们后期管理这些依赖(查看版本,更换版本)
-->
<spring.version>5.3.3</spring.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.2.6</druid.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
使用Maven开发项目
路径问题的建议:
- 不要用绝对路径
- 最好使用类加载器的方式去读文件
切换成Maven之后,开发模式的变化:
- 之前需要手动下
jar
包,拷贝,添加到库文件;现在只用引入坐标 - 之前读配置文件,使用
new FileInputStream()
;现在读配置文件,需要用classLoader
,配置文件的位置需要在src/main/resource
eg:
以连接池中的druid
举例:
public class druidDemo {
public static void main(String[] args) throws Exception {
testNormal();
}
private static void testNormal() throws Exception {
Properties properties = new Properties();
// 1. 绝对路径不要使用
// properties.load(new FileInputStream("druid.properties"));
ClassLoader classLoader = druidDemo.class.getClassLoader();
// 现在配置文件 需要用classLoader拿
// 通过类加载器拿文件,会通过target/classes里面拿
URL resource = classLoader.getResource("druid.properties");
properties.load(new FileInputStream(resource.getPath()));
// 或者
// properties.load(classLoader.getResourceAsStream("druid.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
boolean execute = statement.execute("insert into t_staff(name) values ('zs')");
System.out.println(execute);
}
}
<?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>
<parent>
<groupId>com.coo1heisenberg</groupId>
<artifactId>test_maven</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module1</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<druid.version>1.2.6</druid.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?
characterEncoding=utf8&useSSL=false&serverTimezone=UTC
username=root
password=123456
Junit
Junit是一个被广泛使用的测试工具,可以帮助我们运行我们指定的方法
如何使用Junit
- 导包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
-
使用
@Test
@After
- 修饰的方法会在测试方法运行之后执行
- 在每一次测试方法的前后都会运行
- 一般用来准备数据
@Before
- 修饰的方法会在测试方法运行之前执行
- 在每一次测试方法的前后都会运行
- 一般用来销毁数据
@BeforeClass
@AfterClass
-
使用的注意事项:
@BeforeClass
和@AfterClass
修饰的方法必须是静态的@Test
注解修饰的方法必须是public、必须是void、必须没有参数- 测试类必须在
src/test/java
路径下 - 测试类的命名必须叫做
XxxTest
- 测试方法(@Test注解修饰的方法)的命名必须叫做
testXxx
();
-
使用断言语句,来完成结果的确认
@Test
public void test1() {
// 在单元测试里面,使用Assert 断言帮我们完成自动化的检验工作。
Assert.assertEquals(new Integer(3), max);
}