重新认识maven
本文最后更新于:2022年2月9日 11:19
目标
- 能够快速熟悉公司项目的maven配置,并且能够配置自己的maven配置
- 配置maven,不用再copy,能够做到应用自如
- 开源项目的maven配置文件,不在迷茫
- 能够搭建自己的maven私服,用maven进行企业级的规范工程管理
maven背景
自己依赖的jar,都需要自己copy到lib文件夹中。
- 大型项目依赖的jar,非常多
- 缺少依赖,自己寻找依赖的对应的jar
- 依赖冲突,依赖版本可能不一样
- 单体应用,拆分成多个模块的,每个模块都是一个工程,最后还得将所有的工程合并,编译起来通过统一的入口进行启动。
流程痛苦
自己一顿操作在本地跑起来,然后进行集成测试,然后编译代码,然后手动打包,然后将war\jar部署到服务器,QA测试,出现了bug之后,我们又得本地跑,集成测试,手工打包,编译部署,一直到测试通过
最后,将通过测试的jar或者war,部署到上线生产环境。
结论
效率低下,程序员维护各种jar非常痛苦。
maven如何解决依赖和构建自动化的问题
- 上班,先写代码,然后编写单元测试,接着一个maven test 的命令,maven就自动将项目中单元测试自动哦跑起来,还能自动出来一个完整的单元测试的覆盖率的报告,已经单元测试运行错误的一份报告
- 如果一个系统有多工程,maven会将多个模块工程集成起来,无需手动集成
- 对应依赖,完成自动化,简单配置一下依赖,maven会自动下载依赖的版本,所有依赖下载、版本调解、版本升级等繁琐的事情都交给maven自动完成
- 编译+打包+发布,自动化
- maven对工程进行统一的编译、打包,发布,
总而言之,用了maven之后,在依赖管理、构建管理、模块化拆分管理,全部自动化完成
maven的历史
- make
最原始的工具,不能跨品台 - ant
配置烦杂 - maven
目前还是最有影响力的工具之一 - gradle
不再依赖xml进行配置,基于DSL语言进行构建
未来,预计还是maven和gradle共存的年代
安装maven(Windows or Mac)
- install Jdk environment(java -version —》1.8)
- download maven zip
- set path M2_HOME or MAVEN_OPTS -Xms128 -Xmx512m
- set setting.xml
- mvn help:system will auto download some requirement
maven基本使用
maven快速构建一个工程
mvn archetype:generate -DgroupId=com.jaryoung.demo -DartifactId=first-demo -DarchetypeArtiactId=maven-archetype-quickstart -DinteractiveMode=false
maven的目录约定
1 |
|
pom.xml之初认识
1 |
|
maven对项目进行打包
源代码和单元测试写好之后,可以通过maven进行自动化的单元测试和编译 、打包。
mvn clean package
,会先清空target目录下所有的内容,然后对工程进行构建,构建出来一个可以执行的jar包。
1 |
|
执行jar包
1 |
|
maven架构
maven鸟瞰图
maven重要的知识点
maven坐标
1 |
|
坐标的作用,上面的五个坐标就代表了特定版本的代码,就是特定代码版本的jar包,可以上传到maven的仓库,能够提供给别人下载使用。
总结:
- 坐标的元素(五个g a p v c)
- 每个坐标的意义
- 五个坐标的作用
依赖标签重认识
1 |
|
解决依赖冲突
例子:
A → B → Y(1.0)
A → B → C → Y(2.0)
Y (2.0) 某个接口增加一个方法,所以调用的时候,就会有找不到方法。
解决办法:
使用新版本,一般来说开源项目是会有向后兼容性的。
分析
1 |
|
排除旧版本
1 |
|
maven仓库
目的,为了消除重复jar包,以前没有maven的时候,各个项目都要有自己的lib目录存放各种依赖jar包。
- 本地仓库
- 云端仓库
- 官方中央仓库
- 内网私服
- 阿里云镜像
- …
maven的生命周期以及执行原理
生命周期的图
mvn命令相关的
mvn clean package
mvn clean install
mvn clean deploy
独立的生命周期(phase)
- clean
- pre-clean
- clean
- post-clean
- default
- validate
- initialize
- generate-sources
- process-sources
- process-resources
- compile
- process-classes
- generate-test-sources
- generate-test-resources
- process-test-resources
- test-compile
- process-test-classes
- test
- prepare-package
- package
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install
- deploy
- site(部署文档)
- pre-site
- site
- post-site
- site-deploy
phrase和plugin的绑定
process-resources -》 resources:resources
compile -》 compile:compile
process-test-resources -》 resources:testResources
test-compile -》compiler:testCompile
test -》surefire:test
package -》jar:jar or war:war
install -》install:install
deploy -》deploy:deploy
site -》site:site
clean -》clean:clean
命令行和phrase的关系
mvn clean package
clean,代表是clean 生命周期的中clean phase。
会执行,clean 所有的 操作,也就是上面clean 的1 - 3 步。
package,代表是会执行default中package phase之前所有的操作,当然也包含当前packagephase的操作
mvn dependency:tree
mvn deploy:deploy-file
直接执行,不会执行任何 default上面的生命周期的内容,会直接执行插件的中的goal。例如 ,mvn dependency:tree,直接执行dependency插件中的tree的goal。
plugin配置
1 |
|
maven企业级实战
从0到1搭建一个私服仓库
架构图
下载 neuxs repository
docker pull sonatype/nexus3:latest
启动
1
2
3-v 挂载volume到意思
$PWD 代表到是当前到目录
docker run -d -p 8090:8081 --name nexus -v $PWD/nexus-data:/nexus-data sonatype/nexus3修改maven-central代理仓库中的remote storage
https://repo1.maven.org/maven2/
修改成:https://maven.aliyun.com/repository/central
maven-snapshot和maven-releases宿主仓库已有,无需修改
3rd-party仓库,需要手动创建,并且配置到maven-public group中
选择 maven2(hosted),宿主类型
输入3rd-party,然后创建。
设置maven-public
添加组内,保存,大功告成
本地强制配置走私服
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<pluginGroups>
</pluginGroups>
<proxies>
</proxies>
<servers>
<!--配置专用账号 -->
<server>
<id>nexus-releases</id>
<username>nx-deployment</username>
<password>nx-deployment123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>nx-deployment</username>
<password>nx-deployment123</password>
</server>
<server>
<id>nexus-3rd-party</id>
<username>nx-deployment</username>
<password>nx-deployment123</password>
</server>
</servers>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8090/repository/maven-public/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>neuxs</id>
<repositories>
<repository>
<id>neuxs</id>
<name>neuxs</name>
<url>http://localhost:8090/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>Nexus Plugin Repository</name>
<url>http://localhost:8090/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profiles>
<activeProfiles>
<activeProfile>neuxs</activeProfile>
</activeProfiles>
</settings>权限管理,例如配置一个可以上传的jar的账号,nx-deployment
使用专用的账号,上传
pom文件添加,需要跟setting文件中的 servers 配置server的id一致
1
2
3
4
5
6
7
8
9
10
11
12
13<distributionManagement>
<repository>
<!-- 需要跟setting文件中的 servers 配置server的id一致 -->
<id>nexus-releases</id>
<name>Releases</name>
<url>http://localhost:8090/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Snapshot</name>
<url>http://localhost:8090/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97mvn clean deploy
[WARNING]
[WARNING] Some problems were encountered while building the effective settings
[WARNING] Unrecognised tag: 'pluginRepositories' (position: START_TAG seen ...</profile>\n <pluginRepositories>... @252:25) @ /Users/jaryoung/.m2/settings.xml, line 252, column 25
[WARNING]
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building oa-org 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ oa-org ---
[INFO] Deleting /Users/jaryoung/project/study/maven/oa-org/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ oa-org ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 5 resources
[INFO] Copying 5 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ oa-org ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 5 source files to /Users/jaryoung/project/study/maven/oa-org/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ oa-org ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/jaryoung/project/study/maven/oa-org/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ oa-org ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/jaryoung/project/study/maven/oa-org/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ oa-org ---
[INFO] Surefire report directory: /Users/jaryoung/project/study/maven/oa-org/target/surefire-reports
Downloading from nexus-aliyun: http://maven.aliyun.com/nexus/content/groups/public/org/apache/maven/surefire/surefire-junit4/2.12.4/surefire-junit4-2.12.4.pom
Downloaded from nexus-aliyun: http://maven.aliyun.com/nexus/content/groups/public/org/apache/maven/surefire/surefire-junit4/2.12.4/surefire-junit4-2.12.4.pom (0 B at 0 B/s)
Downloading from nexus-aliyun: http://maven.aliyun.com/nexus/content/groups/public/org/apache/maven/surefire/surefire-junit4/2.12.4/surefire-junit4-2.12.4.jar
Downloaded from nexus-aliyun: http://maven.aliyun.com/nexus/content/groups/public/org/apache/maven/surefire/surefire-junit4/2.12.4/surefire-junit4-2.12.4.jar (0 B at 0 B/s)
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest
log4j:ERROR Could not find value for key log4j.appender.Stdout
log4j:ERROR Could not instantiate appender named "Stdout".
2021-02-20 00:38:22,869 [main] DEBUG [org.springframework.test.context.junit4.SpringJUnit4ClassRunner] - SpringJUnit4ClassRunner constructor called with [class com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest].
2021-02-20 00:38:22,914 [main] DEBUG [org.springframework.test.context.support.AbstractDelegatingSmartContextLoader] - Delegating to GenericXmlContextLoader to process context configuration [ContextConfigurationAttributes@60addb54 declaringClass = 'com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest', classes = '{}', locations = '{classpath*:application-org.xml}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader'].
2021-02-20 00:38:22,915 [main] DEBUG [org.springframework.test.context.ContextLoaderUtils] - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]
2021-02-20 00:38:22,917 [main] DEBUG [org.springframework.test.context.TestContextManager] - @TestExecutionListeners is not present for class [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]: using defaults.
2021-02-20 00:38:22,919 [main] INFO [org.springframework.test.context.TestContextManager] - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
2021-02-20 00:38:22,929 [main] DEBUG [org.springframework.test.annotation.ProfileValueUtils] - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]
2021-02-20 00:38:22,929 [main] DEBUG [org.springframework.test.annotation.ProfileValueUtils] - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]
2021-02-20 00:38:22,930 [main] DEBUG [org.springframework.test.annotation.ProfileValueUtils] - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]
2021-02-20 00:38:22,930 [main] DEBUG [org.springframework.test.annotation.ProfileValueUtils] - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]
2021-02-20 00:38:22,932 [main] DEBUG [org.springframework.test.annotation.ProfileValueUtils] - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]
2021-02-20 0est.context.support.DirtiesContextTestExecutionListener] - After test class: context [[TestContext@50c87b21 testClass = EmployeeServiceImplTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1810399e testClass = EmployeeServiceImplTest, locations = '{classpath*:application-org.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]], dirtiesContext [false].
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.191 sec
2021-02-20 00:38:23,962 [Thread-0] INFO [org.springframework.context.support.GenericApplicationContext] - Closing org.springframework.context.support.GenericApplicationContext@26be92ad: startup date [Sat Feb 20 00:38:23 CST 2021]; root of context hierarchy
2021-02-20 00:38:23,962 [Thread-0] DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'sqlSessionFactory'
2021-02-20 00:38:23,962 [Thread-0] DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'lifecycleProcessor'
2021-02-20 00:38:23,962 [Thread-0] INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@80ec1f8: defining beans [propertyConfigurer,dataSource,sqlSessionFactory,org.mybatis.spring.mapper.MapperScannerConfigurer#0,employeeService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,employeeDao]; root of factory hierarchy
2021-02-20 00:38:23,962 [Thread-0] DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Retrieved dependent beans for bean 'employeeService': [com.jaryoung.oa.org.service.impl.EmployeeServiceImplTest]
Results :
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ oa-org ---
[INFO] Building jar: /Users/jaryoung/project/study/maven/oa-org/target/oa-org-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ oa-org ---
[INFO] Installing /Users/jaryoung/project/study/maven/oa-org/target/oa-org-1.0-SNAPSHOT.jar to /Users/jaryoung/.m2/repository/com/jaryoung/oa-org/1.0-SNAPSHOT/oa-org-1.0-SNAPSHOT.jar
[INFO] Installing /Users/jaryoung/project/study/maven/oa-org/pom.xml to /Users/jaryoung/.m2/repository/com/jaryoung/oa-org/1.0-SNAPSHOT/oa-org-1.0-SNAPSHOT.pom
[INFO]
[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ oa-org ---
Downloading from nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/maven-metadata.xml
Downloaded from nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/maven-metadata.xml (762 B at 28 kB/s)
Uploading to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/oa-org-1.0-20210219.163824-5.jar
Uploaded to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/oa-org-1.0-20210219.163824-5.jar (13 kB at 155 kB/s)
Uploading to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/oa-org-1.0-20210219.163824-5.pom
Uploaded to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/oa-org-1.0-20210219.163824-5.pom (4.9 kB at 68 kB/s)
Downloading from nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/maven-metadata.xml
Downloaded from nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/maven-metadata.xml (276 B at 13 kB/s)
Uploading to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/maven-metadata.xml
Uploaded to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/1.0-SNAPSHOT/maven-metadata.xml (762 B at 12 kB/s)
Uploading to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/maven-metadata.xml
Uploaded to nexus-snapshots: http://localhost:8090/repository/maven-snapshots/com/jaryoung/oa-org/maven-metadata.xml (276 B at 4.6 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.095 s
[INFO] Finished at: 2021-02-20T00:38:24+08:00
[INFO] Final Memory: 23M/190M
[INFO] ------------------------------------------------------------------------上传到3rd-party仓库
mvn deploy:deploy-file -DgroupId=com.stbz -DartifactId=stbz -Dversion=1.0 -Dpackaging=jar -Dfile=$PWD/target/stbz-1.0.jar -Durl=http://localhost:8090/repository/3rd-party/ -DrepositoryId=nexus-3rd-party
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26~/project/study/maven/stbz mvn deploy:deploy-file -DgroupId=com.stbz -DartifactId=stbz -Dversion=1.0 -Dpackaging=jar -Dfile=$PWD/target/stbz-1.0.jar -Durl=http://localhost:8090/repository/3rd-party/ -DrepositoryId=nexus-3rd-party
[WARNING]
[WARNING] Some problems were encountered while building the effective settings
[WARNING] Unrecognised tag: 'pluginRepositories' (position: START_TAG seen ...</profile>\n <pluginRepositories>... @257:25) @ /Users/jaryoung/.m2/settings.xml, line 257, column 25
[WARNING]
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building stbz 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-deploy-plugin:2.8.2:deploy-file (default-cli) @ stbz ---
Uploading to nexus-3rd-party: http://localhost:8090/repository/3rd-party/com/stbz/stbz/1.0/stbz-1.0.jar
Uploaded to nexus-3rd-party: http://localhost:8090/repository/3rd-party/com/stbz/stbz/1.0/stbz-1.0.jar (403 kB at 829 kB/s)
Uploading to nexus-3rd-party: http://localhost:8090/repository/3rd-party/com/stbz/stbz/1.0/stbz-1.0.pom
Uploaded to nexus-3rd-party: http://localhost:8090/repository/3rd-party/com/stbz/stbz/1.0/stbz-1.0.pom (383 B at 1.5 kB/s)
Downloading from nexus-3rd-party: http://localhost:8090/repository/3rd-party/com/stbz/stbz/maven-metadata.xml
Uploading to nexus-3rd-party: http://localhost:8090/repository/3rd-party/com/stbz/stbz/maven-metadata.xml
Uploaded to nexus-3rd-party: http://localhost:8090/repository/3rd-party/com/stbz/stbz/maven-metadata.xml (288 B at 1.7 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.728 s
[INFO] Finished at: 2021-02-21T13:48:37+08:00
[INFO] Final Memory: 10M/204M
[INFO] ------------------------------------------------------------------------配置task,创建日常任务的task
仓库类型
- group:仓库组,虚拟的仓库组。中央仓库:maven1或者maven2
- hosted:宿主仓库,内部发布使用
- proxy:代理仓库,代理各种其他的仓库的。
maven-central:maven中央仓库代理仓库
maven-releases:宿主仓库,用于部署公司内部的发布的release版本项目
maven-snapshots:宿主仓库,用于部署公司内部的发布的snapshot版本项目
3rd party:宿主仓库,用于部署三方的项目
maven public:仓库组,所有release仓库都在这个仓库组
OA需求分析
- 组织模块
包含部门和员工,curd - 权限模块
员工、角色、权限 - 审批模块
员工、申请、审批
从0到1搭建一个spring + mvc + mybatis到项目
- 创建maven项目
- 编写pom依赖
- 配置Spring 、mybatis、日志配置
- 自动生成curd操作和相关到类
- 编写单元测试
开发权限管理模块
idea esay code 自动生成代码
1 |
|
开发流程审批模块
idea esay code 自动生成代
1 |
|
基于聚合功能实现多模块统一构建
1 |
|
基于继承功能将所有模块的依赖版本强制统一
解决父子pom版本统一的问题
1 |
|
依赖集中约束版本号
解决版本依赖统一的问题
1 |
|
基于import pom强制约束依赖方的版本号
组件强制要求依赖方需要使用合理版本依赖,以防止组件在被依赖之后,无法使用的情况。
新建 oa-common的项目,pom文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<?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>com.jaryoung.oa</groupId>
<artifactId>oa-common</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.3</version>
</dependency>
</dependencies>
</project>新建bom文件,也就是一个特殊maven项目,只有pom文件的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<?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>com.jaryoung.bom</groupId>
<artifactId>oa-commons-bom</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.3</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>在 dependencyManagement 通过 import方式导入到项目中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47<?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.jaryoung.oa</groupId>
<artifactId>oa-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>oa-org</artifactId>
<version>1.0-SNAPSHOT</version>
<name>oa-org</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<dependencies>
<dependency>
<groupId>com.jaryoung.oa</groupId>
<artifactId>oa-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.jaryoung.bom</groupId>
<artifactId>oa-commons-bom</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<!-- oa-common-bom 组件的依赖,作为引入组件 oa-common,-->
<!-- 引用的开源或者其他项目的版本依赖 -->
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
开发OA系统的web服务
目录结构
java
resources
—application-web.xml
—spring-servlet.xml
webapp
—WEB-INF
—web.xml
application-web.xml
1 |
|
spring-servlet.xml
1 |
|
web.xml
1 |
|
基于surefire插件运行单元测试以及输出覆盖率报告
surefire 会 跟 Junit 单元测试测试很好的结合
可选项
跳过所有单元测试-不推荐
跳过某些单元测试-不推荐
测试报告
单元测试覆盖率,代表单元测试是否会覆盖到代码的行数,或者方法的覆盖率
引用cobertura插件
1
2
3
4
5<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
</plugin>执行
mvn cobertura:cobertura
命令查看
target/site/index.html
报告
基于jetty插件在本地启动web服务进行功能测试
项目配置jetty本地启动
1
2
3
4
5
6
7
8<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.37.v20210219</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>配置setting文件
1
2
3
4
5
6
7<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
<pluginGroup>org.eclipse.jetty</pluginGroup>
</pluginGroups>在oa-web项目下执行
mvn jetty:run
基于cargo对web服务进行自动化部署
第一步docker安装tomcat镜像
启动 tomcat 镜像,
docker run -d --name tomcat -p 8888:8080
复制配置
1
2
3
4docker cp [contain id]:/usr/local/tomcat/webapps.dist .
mv webapps.dist webapps
docker cp [contain id]:/usr/local/tomcat/conf .
docker cp [contain id]:/usr/local/tomcat/logs .以挂载的方式启动tomcat
docker run -d --name tomcat -p 8888:8080 -v $PWD/conf/:/usr/local/tomcat/conf -v $PWD/webapps/:/usr/local/tomcat/webapps -v $PWD/logs/:/usr/local/tomcat/logs tomcat:latest
修改配置
tomcat-users.xml
和webapps/manager/META-INF/context.xml
1
2
3
4
5tomcat-users.xml
<role rolename="tomcat"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user username="admin" password="admin" roles="tomcat,manager-gui,manager-script"/>1
2
3
4
5
6
7webapps/manager/META-INF/context.xml
<!-- 注释掉访问地址限制 -->
<Context antiResourceLocking="false" privileged="true" >
<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="\d+\.\d+\.\d" /> -->
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>mvn clean package
,打成warmvn clean verify org.codehaus.cargo:cargo-maven3-plugin:deploy
,使用cargo插件部署访问接口
基于资源过滤+profile功能自动适配各个发布环境
配置pom文件夹增加 profiles配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://localhost:3306/oa</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>123456</jdbc.password>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://test:3306/oa</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>123456</jdbc.password>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://prod:3306/oa</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>123456</jdbc.password>
</properties>
</profile>
</profiles>mvn package -Pdev
,看看打出来jar配置是否正确mvn package -Ptest -DskipTests=true
,同上配置 cargo 多环境配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<version>1.9.0</version>
<configuration>
<container>
<containerId>tomcat9x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.hostname>${cargo.hostname}</cargo.hostname>
<cargo.servlet.port>${cargo.servlet.port}</cargo.servlet.port>
<cargo.tomcat.manager.url>${cargo.tomcat.manager.url}</cargo.tomcat.manager.url>
<cargo.remote.username>${cargo.remote.username}</cargo.remote.username>
<cargo.remote.password>${cargo.remote.password}</cargo.remote.password>
</properties>
</configuration>
<deployer>
<type>remote</type>
</deployer>
<deployables>
<deployable>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<type>${project.packaging}</type>
</deployable>
</deployables>
</configuration>
</plugin>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://localhost:3306/oa</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>123456</jdbc.password>
<cargo.hostname>localhost</cargo.hostname>
<cargo.servlet.port>8888</cargo.servlet.port>
<cargo.tomcat.manager.url>http://localhost:8888/manager</cargo.tomcat.manager.url>
<cargo.remote.username>admin</cargo.remote.username>
<cargo.remote.password>admin</cargo.remote.password>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://test:3306/oa</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>123456</jdbc.password>
<cargo.hostname>localhost</cargo.hostname>
<cargo.servlet.port>8888</cargo.servlet.port>
<cargo.tomcat.manager.url>http://test:8888/manager</cargo.tomcat.manager.url>
<cargo.remote.username>test</cargo.remote.username>
<cargo.remote.password>test</cargo.remote.password>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://prod:3306/oa</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>123456</jdbc.password>
<cargo.hostname>localhost</cargo.hostname>
<cargo.servlet.port>8888</cargo.servlet.port>
<cargo.tomcat.manager.url>http://prod:8888/manager</cargo.tomcat.manager.url>
<cargo.remote.username>prod</cargo.remote.username>
<cargo.remote.password>prod</cargo.remote.password>
</properties>
</profile>
</profiles>mvn clean verify org.codehaus.cargo:cargo-maven3-plugin:deploy -Pdev -DskipTests=true
mvn clean verify org.codehaus.cargo:cargo-maven3-plugin:deploy -Ptest -DskipTests=true
进行资源文件的多环境配置
1 |
|
上面主要是增加一个propertie → <env>dev</env>
版本管理和版本控制的区别
maven的版本管理的目的,是管理好maven的对应的版本。
git目的是做好版本控制,也就是给我们能鼓回滚某一个commit的时刻。
互联网公司最佳实践之如何进行版本管理
开发中的版本:x.x.x-SNASHOPT
发布的版本:x.x.x
举个例子
开发中:1.0.1-SNASHOPT → 1.0.2-SNASHOPT(修复某个bug)→1.0.2(发布版本)
重大升级:2.0.1-SNASHOPT → 2.0.2-SNASHOPT(修复某个bug)→2.0.1(发布版本)
第一位,一般相对稳定除非大的变更,第二位,用于次重大变更,第三位用于日常变更
为项目创建统一的工程骨架
Maven - Guide to Creating Archetypes
1 |
|
pom.xml
1 |
|
archetype-metadata.xml
1 |
|
mybatis源码中的pom.xml解释
1 |
|
课程总结
遇到的问题及解决思路
多模块进行聚合的时候,发现部分项目的mamper没有被扫描到。
解决思路,查询日志看那些mapper没有被扫描到
Parsed mapper file:’URL [jar:file:/**/oa-org-1.0-SNAPSHOT.jar!/mapper/AuthorizationDao.xml]’
解决思路:
- 单个项目构建跑单元测试通过,表明配置每个项目的配置是ok
- 调试源码看到只有oa-auth的mapper被扫描到了,其实通过启动日志也能看到扫描那些mapper
- 发现
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
- 问题分析,上面的配置导致多模块聚合的时候,只扫描了oa-auth下面classpath下面的mapper的文件
- 修改
<property name="mapperLocations" value="classpath*:mapper/*.xml"/>
问题解决 - spring配置文件中application-xx.xml多个一致的
property
key配置的时候,主要覆盖的内容喔。
引出问题 classpath: vs classpath*:
Difference between Classpath:* & Classpath*: in Spring
application-org.xml
1 |
|
application-flow.xml
1 |
|
application-auth.xml
1 |
|
1 |
|
日志分析
1 |
|