【Maven教程】(三)基础使用篇:入门使用指南——POM编写、业务代码、测试代码、打包与运行、使用Archetype生成项目骨架~
Maven基础使用篇
- 1️⃣ 编写 POM
- 2️⃣ 编写业务代码
- 3️⃣ 编写测试代码
- 4️⃣ 打包和运行
- 5️⃣ 使用 Archetype生成项目骨架
1️⃣ 编写 POM
到目前为止,已经大概了解并安装好了Maven环境, 现在,我们开始创建一个最简单的 Hello World
项目。如果你是初次接触 Maven, 建议按照本文的内容 一步步地编写代码并执行, 其中可能你会碰到一些概念暂时难以理解,但不用着急,记下这些疑难点,我在后续文章中会逐一进行解答。
就像 Make
的 Makefile
、Ant
的 build.xml
一样 ,Maven 项目的核心是 pom.xml
。POM (Project Object Model, 项目对象模型)
定义了项目的基本信息,用于描述项目如何构建, 声明项目依赖,等等。现在先为 Hello World
项目编写一个最简单的 pom.xml
。
首先创建一个名为 hello-world
的文件夹,打开该文件夹,新建一个名为 pom.xml
的文件,输入其内容,如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven,apache.org/POM/4.0.0"xmins: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.xiaoshan.mvnbook</groupId><artifactId>hello-world</artifactId><version>1.0-SNAPSHOT</version><name>Maven Hello World Project</name>
</project>
代码的第一行是XML 头,指定了该 xml 文档的版本和编码方式。紧接着是 project
元素 ,project
是所有pom.xml
的根元素,它还声明了一些 POM 相关的命名空间及 xsd
元素 , 虽然这些属性不是必须的,但使用这些属性能够让第三方工具(如 IDE 中的XML 编辑器 ) 帮助我们快速编辑 POM。
根元素下的第一个子元素 modelVersion
指定了当前POM 模型的版本,对于 Maven 2 及 Maven 3 来说,它只能是4.0.0。
这段代码中最重要的是包含 groupld
、artifactld
和 version
的三行。这三个元素定义了一个项目基本的坐标,在Maven 的世界,任何的 jar
、pom
或者 war
都是以基于这些基本的坐标进行区分的。
groupld
定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联。譬如在 googlecode 上建立了一个名为 myapp 的项目,那么 groupld
就应该是 com. googlecode.myapp
, 如果你的公司是 mycom, 有一个项目为 myapp, 那 groupld
就应该是 com.mycom.myapp
。artifactld
定义了当前Maven 项目在组中唯一 的ID, 我们为这个 Hello World
项目定义 artifactld
为 hello-world
。 而在前面的 groupId
为 com. googlecode.myapp
的例子中,你可能会为不同的子项目(模块)分配 artifactId
, 如 myapp-util
、myapp-domain
、myapp-web
等。
顾名思义, version
指定了 Hello World
项目当前的版本 — — 1.0-SNAPSHOT
。SNAPSHOT 意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的发展, version
会不断更新,如升级为1.0
、1.1-SNAPSHOT
、1.1
、2.0
等。后面文章会详细介绍 SNAPSHOT 以及如何使用Maven 管理项目版本的升级发布。
最后一个 name
元素声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个 POM 声明 name
, 以方便信息交流。
没有任何实际的Java代码,我们就能够定义一个Maven 项目的 POM, 这体现了 Maven 的一大优点,它能让项目对象模型最大程度地与实际代码相独立,我们可以称之为解耦,或者正交性。这在很大程度上避免了Java 代码和 POM 代码的相互影响。比如当项目需要升级版本时,只需要修改 POM, 而不需要更改 Java代码;而在 POM 稳定之后,日常的 Java 代码开发工作基本不涉及 POM 的修改。
2️⃣ 编写业务代码
项目业务代码和测试代码不同,项目的业务代码会被打包到最终的构件中(如 jar), 而 测试代码只在运行测试时用到,不会被打包。默认情况下, Maven 假设项目业务代码位于 src/ main/java
目录,我们遵循 Maven的约定,创建该目录,然后在该目录下创建文件 com/xiaoshan/mvnbook/helloworld/HelloWorld.java
, 其内容如下所示:
package com.xiaoshan.mvnbook.helloworld;public class HelloWorld{public String sayHello(){return "Hello Maven";}public static void main(String[] args){System.out.print(new HelloWorld().sayHello());}
}
这是一个简单的Java 类,它有一个sayHello()
方法,返回一个String。 同时这个类还带有一个main
方法 , 创建一个HelloWorld
实例 , 调用sayHello()
方法,并将结果输出到控制台。
关于该Java代码有两点需要注意。首先,在绝大多数情况下,应该把项目主代码放到 src/main/java/
目录下 ( 遵循 Maven的约定), 而无须额外的配置,Maven 会自动搜寻该目录找到项目主代码。其次,该Java 类的包名是 com.xiaoshan. mvnbook. helloworld
, 这与之前在 POM 中定义的 groupId
和 artifactId
相吻合。 一般来说,项目中Java 类的包都应该基于项目的 groupId
和 artifactId
, 这样更加清晰,更加符合逻辑,也方便搜索构件或者Java 类 。
代码编写完毕后,使用Maven 进行编译,在项目根目录下运行命令 mvn clean compile
。会得到如下输出:
[INFO] Scanning for projects..
[INFO]
-----------------------------------------------------------------------
[INFO] Building Maven Hello World Project
[INFO] task-segment:[clean, compile]
[INFO]
-----------------------------------------------------------------------
[INFO] [clean:clean {execution:default-clean}]
[INF0] Deleting directory D:\code\hello-world\target
[INF0] [resources:resources {execution:default-resources}]
[INFO] skip non existing resourcepirectory D:\code\hello-world\src\main\resources
[INFO] [compiler:compile {execution:default-compile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\classes
[INFO]
-----------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO]
-----------------------------------------------------------------------
[INFO] Total time:1 second
[INFO] Finished at: Fri oct 0902:08:09 CST 2009
[INFO] Final Memory:9M/16M
-----------------------------------------------------------------------
clean
指令告诉 Maven 清理输出目录 target/
,compile
告诉 Maven 编译项目主代码,从输出中看到 Maven 首先执行了 clean:clean
任务,删除targel/
目录。默认情况下, Maven 构建的所有输出都在 target/
目录中;接着执行 reources:resources
任务 (未定义项目资源 ,暂且略过 ) ; 最后执行 compiler:compile
任务 , 将项目主代码编译至 target/classes
目录 ( 编译好的类为 com/xiaoshan/mvnbook/helloworld/HelloWorld.class
)。
上文提到的 clean:clean, resources: resources 和 compiler:compile
对应了一些 Maven 插件及插件目标,比如 clean:clean
是 clean 插件的 clean 目标 ,compiler:compile
是 compiler 插件的 compile 目标。后文会详细讲述 Maven 插件及其编写方法。
至此 ,Maven 在没有任何额外的配置的情况下就执行了项目的清理和编译任务。接下来,编写一些单元测试代码并让 Maven 执行自动化测试。
3️⃣ 编写测试代码
为了使项目结构保持清晰,业务代码与测试代码应该分别位于独立的目录中。上文讲到过 Maven 项目中默认的主代码目录是 src/main/java
, 对应地,Maven 项目中默认的测试代码目录是 src/test/java
。因此,在编写测试用例之前,应当先创建该目录。
在Java 中,由 Kent Beck 和 Erich Gamma建立的JUnit 是事实上的单元测试标准。要使用JUnit, 首先需要为 Hello World
项目添加一个JUnit 依赖,修改项目的 POM 如下所示:
<?xml version="1.0" encoding="UTP-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.xiaoshan.mvnbook</groupld><artifactId>helloworld</artifactId><version>1.0-SNAPSHOT</version><name>Maven Hello World Project</name><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.7</version><scope>test</scope></dependency></dependencies>
</project>
代码中添加了dependencies
元素,该元素下可以包含多个 dependency
元素以声明项目的依赖。这里添加了一个依赖 —— groupId
是 junit
, artifactId
是 junit
, version
是 4.7。前面提到 groupId
、artifactId
和 version
是任何一个 Maven 项目最基本的坐标,JUnit 也不例外,有了这段声明,Maven 就能够自动下载 junit-4.7.jar
。也许你会问,Maven 从哪里下载这个 jar 呢? 在 Maven 之前,可以去JUnit 的官方网站下载分发包,有了Maven, 它会自动访问中央仓库 (http://repol.maven.org/maven2/
), 下载需要的文件。大家也可以自己访问该仓库,打开路径 junit/junil/4.7/
, 就能 看到 junit-4.7.pom
和 junil-4.7.jar
。后面会详细介绍 Maven 仓库及中央仓库。
上述 POM 代码中还有一个值为 test
的元素 scope
, scope
为依赖范围,若依赖范围为test
则表示该依赖只对测试有效。换句话说,测试代码中的 import
JUnit 代码是没有问题的 ,但是如果在主代码中用 import JUnit 代码,就会造成编译错误。如果不声明依赖范围,那么默认值就是 compile
, 表示该依赖对主代码和测试代码都有效。
配置了测试依赖,接着就可以编写测试类。回顾 一 下前面的 HelloWorld
类 , 现在要测试该类的 sayHello()
方法, 检查其返回值是否为 “Hello Maven
”。 在 src/test/java
目录下创建文件,其内容如下所示:
package com.xiaoshan.mvnbook.helloworld;import org.junit.Assert.assertEquals;
import org.junit.Test:public class HelloWorldTest{@Testpublic void testSayHello(){He1loWorld helloWorld = new HelloWorld();String result = helloWorld.sayHello();assertEquals("Hello Maven",result);}
}
一个典型的单元测试包含三个步骤:①准备测试类及数据;②执行要测试的行为;③检查结果。上述样例首先初始化了一个要测试的HelloWorld
实例,接着执行该实例的sayHello()
方法并保存结果到result
变量中,最后使用JUnit框架的Assert
类检查结果是否为我们期望的“HelloMaven
”。在JUnit3中,约定所有需要执行测试的方法都以test
开头,这里使用了JUnit4,但仍然遵循这一约定。在JUnit4中,需要执行的测试方法都应该以@Test
进行标注。
测试用例编写完毕之后就可以调用 Maven 执行测试。运行 mvn clean test
:
[INFO] Scanning for projects.
[INFO]
-------------------------------------------------------------------
[INFO] Building Maven Hello World Project
[INFO] task-segment:[clean, test]
[INFO]
-------------------------------------------------------------------
[INFO] [elean:clean {execution:default-clean}]
[INFO] Deleting directory D:\git-juven\mvnbook\code\hello-world\target
[INFO] [resources:resources {execution:default-resources)]
Downloading:http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.pom1K downloaded (junit-4.7.pom)
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\classes
[INF0] [resources:testResources {execution:default-testResources}]
Downloading: http://repol,maven.org/maven2/junit/junit/4.7/unit-4.7.jar226K downloaded (Junit-4.7.jar)
[INFO] [compiler:testCompile {execution:default-testCompile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\test-classes
[INFO]
-------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO]
-------------------------------------------------------------------
[INFO] Compilation failure
D:\code\hello-world\src\test\java\com\xiaoshan\mvnbook\helloworld\He11oWorldTest.java;[8,5]-source 1.3 中不支持注释(请使用-source 5 或更高版本以启用注释) @Test
[INFO]
[INFO For more information, run Maven with the switch
不幸的是构建失败了 , 先耐心分析一下这段输出。命令行输入的是 mvn clean test
, 而 Maven 实际执行的可不止这两个任务 , 还 有 clean:clean
、resources:resources
、compiler:compile
、resources:testResources
以及compiler:testCompile
。 暂时需了解的是, 在Maven 执行测试 (test) 之前 , 它会先自动执行项目主资源处理、主代码编译、测试资源处理、测试代码编译等工作,这是 Maven 生命周期的一个特性。后续章节会详细解释 Maven 的生命周期。
从输出中还看到:Maven从中央仓库下载了junit-4.7.pom
和 junit-4.7.jar
这两个文件到本地仓库(~/. m2/repository
)中,供所有Maven项目使用。
构建在执行 compiler:testCompile
任务的时候失败了,Maven输出提示我们需要使用 source5或更高版本以启动注释,也就是前面提到的JUnit4的@Test
注解。这是Maven初学者常常会遇到的一个问题。由于历史原因,Maven的核心插件之———compiler
插件默认只支持编译Java1.3, 因此需要配置该插件使其支持Java5,如下所示:
<project><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.5</source><target>1.5c/target></configuration></plugin></plugins></build>
</project>
该 POM 省略了除插件配置以外的其他部分。我们暂且不去关心插件配置的细节,只需知道 compiler
插件支持Java5 的编译。现在再执行mvn clean test
, 输出如下:
[INFO] [compiler:testCompile {execution:default-testCompile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\test-classes
[INFO] [surefire:test {execution:default-test}]
[INFO] Surefire report directory:D:\code\hello-world\target\surefire-reports
TESTS
Running com.xiaoshan.mvnbook.helloworld.He11oWorldTest
Tests run:1, Failures:0, Errors:0, Skipped:0,Time elapsed:0.055 sec
Results:
Tests run:1, Failures;0.Errors:0,Skipped:0
[INFO]
-------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO]
-------------------------------------------------------------------
我们看到 compiler:testCompile
任务执行成功了,测试代码通过编译之后在 target/test-classes
下生成了二进制文件,紧接着 surefire:test
任务运行测试, surefire
是 Maven 中负责执行测试的插件,这里它运行测试用例 HelloWorldTest
, 并且输出测试报告,显示一共运行了多少测试,失败了多少,出错了多少,跳过了多少。显然,我们的测试通过了。
4️⃣ 打包和运行
将项目进行编译、测试之后,下一个重要步骤就是打包(package
)。HelloWorld
的POM中没有指定打包类型,使用默认打包类型 jar。简单地执行命令mvn clean package
进行打包,可以看到如下输出:
...
Tests run:1,Failures:0, Errors:0, Skipped:0[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar:D:\code\hello-worid\target\hello-wor1d-1.0-SNAPSHOT.Jar
[INPO]
-------------------------------------------------------------------
[INPO] BUILD SUCCESSFUL
...
类似地, Maven 会在打包之前执行编译、测试等操作。这里看到 jar:jar
任务负责打包,实际上就是 jar 插件的 jar 目 标将项目主代码打包成一个名为 hello-world-1.0-SNAP-SHOT.jar
的文件。该文件也位于 target/
输出目录中,它是根据 artifact-version.jar
规则进行命名的,如有需要,还可以使用 finalName
来自定义该文件的名称,这里暂且不展开,后面会详细解释。
至此,我们得到了项目的输出,如果有需要的话,就可以复制这个jar 文件到其他项目的 Classpath 中从而使用 HelloWonld
类。但是,如何才能让其他的Maven 项目直接引用这个jar呢? 还需要一个安装的步骤,执行 mvn clean install
:
...
[INFO] [jar:jar {execution: default-jar}]
[INF0] Building jar:D:\code\hello-world\target\hello-world-1.0-SNAPSHOT.jar
[INFO] [install:install {execution:default-instal1}]
[INFO] Installing D:\code\hello-world\target\hello-wor1d-1.0-SNAPSHOT.jar to c:\Users\xiaoshan\.m2\repository\com\xiaoshan\mvnbook\hello-world\1.0-SNAPSHOTN\hello-world-1.0-SNAPSHOT.jar
[INFO]
-------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
...
在打包之后,又执行了安装任务 install:install
。从输出可以看到该任务将项目输出的 jar安装到了Maven本地仓库中,可以打开相应的文件夹看到 HelloWorld
项目的 pom和 jar。之前讲述JUnit的POM及jar的下载的时候,我们说只有构件被下载到本地仓库后,才能由所有Maven项目使用,这里是同样的道理,只有将HelloWorld
的构件安装到本地仓库之后,其他Maven项目才能使用它。
我们已经体验了Maven最主要的命令:mvn clean compile
、mvn clean test
、mvn clean package
、mvn clean install
。执行test
之前是会先执行compile
的,执行package
之前是会先执行test
的,而类似地,install
之前会执行package
。可以在任何一个Maven项目中执行这些命令,而且我们已经清楚它们是用来做什么的。
到目前为止,还没有运行HelloWorld项目,不要忘了HelloWorld类可是有一个main
方法的。默认打包生成的jar是不能够直接运行的,因为带有main方法的类信息不会添加到 manifest
中(打开 jar文件中的META-INF/MANIFEST.MF
文件,将无法看到 Main-Class
—行)。为了生成可执行的 jar文件,需要借助 maven-shade-plugin
,配置该插件如下:
<plugin><groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.2.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource. ManifestResourceTransformer"><mainClass>com.xiaoshan.mvnbook.helloworld.HelloWorld</mainclass></transformer> </transformers></configuration></execution></executions>
</plugin>
plugin
元素在POM中的相对位置应该在<project>
<build>
<plugins>
下面。我们配置了mainClass
为com.xiaoshan.mvnbook.helloworld.HelloWorld
, 项目在打包时会将该信息放到 MANIFEST
中。现在执行mvn clean install
, 待构建完成之后打开 target/
目录,可以看到 hello-world-1.0-SNAPSHOT.jar
和 original-hello-world-1.0-SNAPSHOT.jar
, 前者是带有 Main-Class
信息的可运行jar, 后者是原始的jar, 打开 hello-world-1.0-SNAPSHOT.jar
的 META-INF/ MANIFEST.MF
, 可以看到它包含这样一行信息:
Main-Class:com.xiaoshan.mvnbook.helloworld.HelloWorld
现在,在项目根目录中执行该jar文件:
D:\code\hello-world>java-jartarget\hello-world-1.0-SNAPSHOT.jar
HelloMaven
控制台输出为HelloMaven,这正是我们所期望的。
5️⃣ 使用 Archetype生成项目骨架
HelloWorld项目中有一些Maven的约定:在项目的根目录中放置pom.xml
,在 src/main/java
目录中放置项目的主代码,在 src/test/java
中放置项目的测试代码。之所以一步一步地展示这些步骤,是为了能让可能是Maven初学者的你得到最实际的感受。我们称这些基本的目录结构和 pom.xml
文件内容称为项目的骨架,当第一次创建项目骨架的时候,你还会饶有兴趣地去体会这些默认约定背后的思想,第二次,第三次,你也许还会满意自己的熟练程度,但第四、第五次做同样的事情,你可能就会恼火了。为此Maven提供了 Archetype
以帮助我们快速勾勒出项目骨架。
还是以HelloWorld为例,我们使用maven archetype
来创建该项目的骨架,离开当前的Maven项目目录。
如果是Maven3,简单地运行:
mvn archetype:generate
如果是Maven2,最好运行如下命令:
mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate
很多资料会让你直接使用更为简单的mvn archetype:generate
命令,但在Maven2中这是不安全的,因为该命令没有指定Archetype插件的版本,于是Maven会自动去下载最新的版本。进而可能得到不稳定的SNAPSHOT版本,导致运行失败。然而在Maven3中,即使用户没有指定版本,Maven也只会解析最新的稳定版本,因此这是安全的。
我们实际上是在运行插件maven-archetype-plugin
,注意冒号的分隔,其格式为groupld:arifactld:version:goal
, orgapache.maven.plugins
是maven官方插件的groupId
, maven-archetype-plugin
是Archetype插件的artifactId
, 2.0-alpha-5
是目前该插件最新的稳定版,generate
是要使用的插件目标。
紧接着会看到一段长长的输出,有很多可用的Archelype供选择,包括著名的 Appfuse
项目的Archetype、JPA
项目的Archetype等。每一个Archetype前面都会对应有一个编号,同时命令行会提示一个默认的编号,其对应的Archetype为 maven-archetype-quickstart
, 直接回车以选择该Archelype, 紧接着Maven会提示输入要创建项目的groupId
、artifactId
、version
以及包名package
。如下输入并确认:
Define value for groupId:: com.xiaoshan.mvnbook
Define value for artifactId::hello-world
Define value for version::1.0-SNAPSHOT
Define value for package:com.xiaoshan.mvnbook::com.xiaoshan.mvnbook.helloworld
Confirm properties configuration:
groupId: com.juvenxu.mvnbook
artifactId: hello-world
version: 1.0-SNAPSHOT
package: com.xiaoshan.mvnbook.helloworld
Y::Y
Archetype插件将根据我们提供的信息创建项目骨架。在当前目录下,Archetype插件会创建一个名为 hello-world
(我们定义的artifactId
)的子目录,从中可以看到项目的基本结构:基本的pom.xml
已经被创建,里面包含了必要的信息以及一个junit依赖;主代码目录src/main/java
已经被创建,在该目录下还有一个Java类com.xiaoshan.mvnbook.helloworld.App
, 注意这里使用到了刚才定义的包名,而这个类也仅仅只有一个简单的输出Hello World!
的 main
方法;测试代码目录 src/test/java
也被创建好了,并且包含了一个测试用例com.xiaoshan.mvnbook.helloworld.AppTest
。
Archetype可以帮助我们迅速地构建起项目的骨架,在前面的例子中,我们完全可以在Archetype生成的骨架的基础上开发HelloWorld
项目以节省大量时间。
此外,这里仅仅是看到了一个最简单的Archetype,如果有很多项目拥有类似的自定义项目结构以及配置文件,则完全可以一劳永逸地开发自己的Archetype,然后在这些项目中使用自定义的Archetype来快速生成项目骨架。后面我会详细阐述如何开发Maven Archetype。
相关文章:
【Maven教程】(三)基础使用篇:入门使用指南——POM编写、业务代码、测试代码、打包与运行、使用Archetype生成项目骨架~
Maven基础使用篇 1️⃣ 编写 POM2️⃣ 编写业务代码3️⃣ 编写测试代码4️⃣ 打包和运行5️⃣ 使用 Archetype生成项目骨架 1️⃣ 编写 POM 到目前为止,已经大概了解并安装好了Maven环境, 现在,我们开始创建一个最简单的 Hello World 项目。如果你是初次…...
Spring Boot + Spring Data JPA 实现数据库操作的标准示例
环境搭建 本篇使用H2内存数据库演示Spring Data JPA 的使用。 导入JPA和H2的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><…...
JVM——类加载器
回顾一下类加载过程 类加载过程:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。 一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义…...
async/await 编程理解
博客主要是参考 Asynchronous Programming in Rust ,会结合简单的例子,对 async 和 await 做比较系统的理解,如何使用 async 和 await 是本节的重点。 async 和 await 主要用来写异步代码,async 声明的代码块实现了 Future 特性&a…...
1. Java基础知识介绍
文章目录 1. Java基础知识介绍1. 简单输入输出1.1 输入1.2 输出 2. 数据类型2.1 基本数据类型2.2 引用数据类型 3. 函数4. 类基础知识5. 小结 1. Java基础知识介绍 1. 简单输入输出 在Java编程中,我们经常需要与用户进行交互,以获取输入并输出结果。Ja…...
基础shell小技巧01
1. 命令替换 shell脚本中最有用的特性之一是可以从命令输出中提取信息并将其赋给变量。把输出赋给变量之后,就可以随意在脚本中使用了。在脚本中处理数据时,这个特性显得尤为方便。 有两种方法可以将命令输出赋给变量。 反引号(࿰…...
微信小程序--data的赋值与取值的几种方式
通过小程序官方文档可知: 赋值一定需要注意。需要setData的使用,这样页面才刷新,数据才会改变,并且分清that和this的使用 Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事…...
条码通讯配置
由Leuze(劳易测) LSIS 222 M5M-R1/MA208i系统组成 连接说明及器件明细: 打开条码调试软件BPS Configuration tool对M208i进行ip 和端口号进行配置,条码选择作为客户端,输入ip和端口号,选择串口通讯波特…...
知网G4期刊《高考》简介及投稿要求
知网G4期刊《高考》简介及投稿要求 一、《高考》期刊简介: 主管单位:长春市委宣传部 主办单位:长春出版社 国内刊号22-1372/G4 国际刊号1673-6265 代号12-240 编辑单位:《高考》杂志社 出版周期:旬刊 类 …...
第7章 CPU前端优化
接下来讨论如何使用CPU监控特性寻找CPU上运行的代码中可被调优的位置。 标准的算法和数据结构在性能敏感型工作负载并不总能表现的很好。例如,在“扁平化”数据结构的冲击下,链表基本上快被放弃了。传统链表中的每个节点都是动态分配的,除了…...
idea新建Java-maven项目时,出现Dependency‘xxx(jar包名)‘ not found的解决方案
项目场景: 项目场景:使用idea创建maven项目时,导入简单依赖时(本文以mysql-connector-java为例)。 问题描述 问题: 首先,在创建新的maven项目中,出现下列两种情况: &am…...
STM32--USART串口
文章目录 通信接口串口通信硬件电路电平标准参数时序 USART主要特性框图 数据帧发送器 波特率发生器SWART串口发送与接收工程串口收发数据包 通信接口 通信接口是指连接中央处理器(CPU)和标准通信子系统之间的接口,用于实现数据和控制信息在不…...
2023年Java毕业设计题目推荐,怎样选题?500道毕业设计题目推荐
大家好,我是程序员徐师兄,最近有很多同学咨询,说毕业设计了,不知道选怎么题目好,有哪些是想需要注意的。 今天,我整理了一些Java毕业设计的题目,可以参考一下,希望对大家有所帮助 文章目录 一、…...
基于数据湖的多流拼接方案-HUDI概念篇
目录 一、为什么需要HUDI? 1. 传统技术选型存在哪些问题? 2. Hudi有什么优点? 基于 Hudi Payload 机制的多流拼接方案: 二、HUDI的应用场景 1. 什么场景适合使用hudi? 2. 什么场景不适合使用hudi? …...
OpenCV基础知识(5)— 几何变换
前言:Hello大家好,我是小哥谈。OpenCV中的几何变换是指改变图像的几何结构,例如大小、角度和形状等,让图像呈现出缩放、翻转、旋转和透视效果。这些几何变换操作都涉及复杂、精密的计算。OpenCV将这些计算过程都封装成了非常灵活的…...
Linux下源码安装MySQL 8.0
MySQL 8.0源码安装 环境准备步骤 环境准备 Linux环境,本文基于CentOS 8 MySQL安装包,本文基于MySQL 8.1,以下为带boost MySQL 8.1源码下载地址: https://dev.mysql.com/get/Downloads/MySQL-8.1/mysql-boost-8.1.0.tar.gz 步骤…...
大聪明教你学Java | 深入浅出聊 Java 内存模型
前言 🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。 🍊支持作者: 点赞👍、关注💖、留言💌~ 在多线程环境下,多个线程同时访问共享数据可能导致一系列问题,如数据不一致、竞态条件和死锁等…...
SAP ABAPG开发屏幕自动生成日期的搜索帮助
代码如下: REPORT z_jason_test_f4 . TABLES: s031. PARAMETER p_spmon TYPE spmon DEFAULT sy-datum0(6) OBLIGATORY. SELECT-OPTIONS s_spmon FOR s031-spmon DEFAULT sy-datum0(6) OBLIGATORY. AT SELECTION-SCREEN ON VALUE-REQUEST…...
leetcode 674. 最长连续递增序列
2023.8.24 与最长递增子序列 类似,不同的是, 本题要求连续序列,所以不需要第二层遍历比较之前所有的元素了,只需要比较上一个元素i-1。 dp[i]的含义为:以nums[i]元素为结尾的序列的最长递增子序列。 注意这里是以i为结…...
Mysql简短又易懂
MySql 连接池:的两个参数 最大连接数:可以同时发起的最大连接数 单次最大数据报文:接受数据报文的最大长度 数据库如何存储数据 存储引擎: InnoDB:通过执行器对内存和磁盘的数据进行写入和读出 优化SQL语句innoDB会把需要写入或者更新的数…...
vue 简单实验 v-model 变量和htm值双向绑定
1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"two-way-binding"><p>{{ message }}</p><input v-model"message" /> </div> <script>…...
测试框架pytest教程(8)失败重试-pytest-rerunfailures
pytest-rerunfailures是一个pytest插件,用于重新运行失败的测试用例。当测试用例在第一次运行时失败,该插件会自动重新运行指定次数的失败用例,以提高稳定性和减少偶发性错误的影响。 要使用pytest-rerunfailures插件,需要按照以…...
6个主流的工业3D管道设计软件
3D 管道设计软件是大多数行业工程工作的主要部分,例如: 电力、石油和天然气、石化、炼油厂、纸浆和造纸、化学品和加工业。 全球各工程公司使用了近 50 种工厂或管道设计软件。 每个软件都有优点和缺点,包括价格点。 EPC 和业主部门当前的趋势…...
基于微信小程序的垃圾分类系统设计与实现(2.0 版本,附前后端代码)
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 1 简介 视频演示地址: 基于微信小程序的智能垃圾分类回收系统,可作为毕业设计 小…...
基础论文学习(4)——CLIP
《Learning Transferable Visual Models From Natural Language Supervision》 CLIP的英文全称是Contrastive Language-Image Pre-training,即一种基于对比文本-图像对的预训练模型。CLIP是一种基于对比学习的多模态模型,与CV中的一些对比学习方法如moc…...
SpringBoot利用ConstraintValidator实现自定义注解校验
一、前言 ConstraintValidator是Java Bean Validation(JSR-303)规范中的一个接口,用于实现自定义校验注解的校验逻辑。ConstraintValidator定义了两个泛型参数,分别是注解类型和被校验的值类型。在实现ConstraintValidator接口时&…...
十、pikachu之php反序列化
文章目录 1、php反序列化概述2、实战3、关于Magic function4、__wakeup()和destruct() 1、php反序列化概述 在理解这个漏洞前,首先搞清楚php中serialize(),unserialize()这两个函数。 (1)序列化serialize():就是把一个…...
PHP“牵手”拼多多商品详情数据获取方法,拼多多API接口批量获取拼多多商品详情数据说明
拼多多商品详情接口 API 是开放平台提供的一种 API 接口,它可以帮助开发者获取拼多多商品的详细信息,包括商品的标题、描述、图片等信息。在拼多多电商平台的开发中,拼多多详情接口 API 是非常常用的 API,因此本文将详细介绍拼多多…...
前端面试:【Redux】状态管理的精髓
嘿,亲爱的Redux探险家!在前端开发的旅程中,有一个强大的状态管理工具,那就是Redux。Redux是一个状态容器,它以一种可预测的方式管理应用的状态,通过Store、Action、Reducer、中间件和异步处理等核心概念&am…...
element-ui中的el-table的summary-method(合计)的使用
场景图片: 图片1: 图片2: 一:使用element中的方法 优点: 直接使用summary-method方法,直接,方便 缺点: 只是在表格下面添加了一行,如果想有多行就不行了 1:h…...
网站pc端网址和手机端网址建设/网络营销方案设计
今日突发奇想,欲找一个在线的 语音留言系统。结果一搜索,出来结果甚少,大致如下: MyChingo:是一个 语音留言系统,它提供一个播放器,播放器的列表窗口中把读者的 语音留言全部列出来,…...
农村基本制度建设网站/整站优化 快速排名
一.获取原生DOM的方式 给标签或者属性添加ref属性 1 //1.添加属性 2 <div refshy><div> 3 <Home refhome></Home> 4 //2.获取原始DOM 5 this.$refs.shy 6 //3.组件实例化对象 7 this.$refs.home 使用实例 1 <body>2 <div id"app"&g…...
烟台网站建设外贸/java培训班学费一般多少
在该示例中,可选地使用LSA(使用SVD)来执行维度缩减。在为什么这个有用?已经可以在TF-IDF矢量器中使用“max_features”参数控制尺寸(特征)的数量。在我知道LSA(和LDA)也是主题建模技术。与聚类的区别在于,文档属于多个主题,但只属…...
网站的通知栏一般用什么控件做/济南优化网站的哪家好
之前一直用的是httpclient,今天okhttp简单封装了一下,主要有三个方法 发送get请求发送post请求,请求体是json字符串发送post请求,可以什么都不传,可以是简单的表单提交,也可以是带文件上传的表单提交 post…...
建网站有什么好处/教育培训学校
mapper.xml文件 <!-- 添加信息 --> <insert id"insert" parameterType"实体类" useGeneratedKeys"true" keyProperty"id"> <!-- 添加送达大信息的同时获取自动生成的ID的值 --> <selectKey resultType&q…...
网站建设微信群/广东网站seo
用友NC全功能说明用友UFIDA NCV5.7产品发版说明目 录1. 产品概述32. 产品特性103. 特别注意事项223.1 客户化223.2 电子采购224. 产品范围235. 产品主要功能245.1 客户化平台部分245.2 客户化基础数据285.3 NMC智能监控335.4 UFESB365.5 财务会计385.6 报表管理595.7 计划预算6…...