第一章:Nexus 私服简介

  • 如果我们已经掌握了 Maven 构建工具,那么对于 Nexus 私服并不陌生,因为在 Maven 的时代,在一个项目团队的内部如果要对自己的代码进行维护,同时也为了节约带宽,往往会搭建自己的私服仓库,例如:之前使用的阿里的 Maven 镜像。
  • 在之前配置的时候,创建了一个 init.gradle 配置文件:
  1. allprojects {
  2. repositories {
  3. def ALIYUN_REPOSITORY_URL = 'https://maven.aliyun.com/repository/central'
  4. def ALIYUN_JCENTER_URL = 'https://maven.aliyun.com/repository/public'
  5. all {
  6. ArtifactRepository repo ->
  7. if (repo instanceof MavenArtifactRepository) {
  8. def url = repo.url.toString()
  9. if (url.startsWith('https://repo1.maven.org/maven2')) {
  10. project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
  11. remove repo
  12. }
  13. if (url.startsWith('https://jcenter.bintray.com/')) {
  14. project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL."
  15. remove repo
  16. }
  17. }
  18. }
  19. maven {
  20. url ALIYUN_REPOSITORY_URL
  21. url ALIYUN_JCENTER_URL
  22. }
  23. }
  24. }
  • 如果开发者要搭建属于自己的私服,就需要通过一些第三方的组件来完成了,一旦私服搭建成功,就可以方便所有开发者进行仓库程序的管理。

1.png

  • 在实际的开发之中,所有程序所需要的依赖库实际上都可以通过 中央仓库 进行所有依赖库坐标的查找,但是如果要想在这个网站上公布自己的开源的项目,那么一般都需要通过特定的认证机构来完成,但是一般的开发公司,肯定有一些属于自己的核心类库,这个时候就不方便进行公布了。

2.png

  • 所有可以查找到的开源项目都需要提供有完整的官方认证,否则是不能进行项目(依赖库)的发布,国内因为防火墙的原因,所以一般需要有一个专属的国内的镜像仓库来进行国外仓库的缓存,如:阿里的 Maven 镜像。
  • 如果想进行私服的搭建,必须要求该私服一定可以连接到国内的镜像,同时还需要有完善的用户认证管理体系。
  • 对于构建工具(Maven、Gradle)的私服来说,都是通过 sonatype 公司出品的 nexus 工具来实现整个私服的维护。
  • 如果要进行 nexus 私服工具的下载,可以访问 nexus 的下载地址。

3.png

  • 当注册完成后,会出现如下的页面,这表明了 nexus 支持 Windows、Linux 和 Mac 操作系统,可以直接下载所需要的程序包。

4.png

  • 本次使用的是 Linux 版本的 nexus,而当前获得下载包的名称是 nexus-3.24.0-02-unix.tar.gz ,本次使用的操作系统是 CentOS 7.9

第二章:Nexus 私服安装

2.1 准备工作

操作系统 nexus 版本 操作系统 IP
CentOS 7.9 nexus-3.24.0-02-unix.tar.gz 192.168.65.100

2.2 关闭 Linux 的防火墙

  • 命令:
  1. systemctl stop firewalld
  1. systemctl disable firewalld

2.3 nexus 上传

  • 将 nexus 通过 ftp 上传到 Linux 系统之中(略),上传的目录是 /opt 。

2.4 nexus 解压缩

  • 解压:
  1. cd /opt
  1. tar -zxvf nexus-3.24.0-02-unix.tar.gz -C /usr/local/

5.gif

2.5 nexus 配置

  • 为了方便进行私服的访问,可以修改一下 nexus 启动的端口号,这个端口号直接通过修改配置文件来进行修改。
  • 进入到 nexus 的目录:
  1. cd /usr/local/nexus-3.24.0-02

6.gif

  • 修改配置文件:
  1. cd etc
  1. vim nexus-default.properties
  1. # 修改
  2. application-port=80
  3. application-host=0.0.0.0

7.gif

2.6 nexus 启动

  • 配置完成之后就可以直接通过命令启动 nexus 服务。
  • 启动 nexus 服务:
  1. cd ..
  1. cd bin
  1. ./nexus start

8.gif

2.7 访问

  • 直接在 Windows 系统上通过浏览器输入 192.168.65.100 即可。

9.png

第三章:Nexus 私服配置

3.1 概述

  • 通过一系列的操作已经成功的在系统中配置了 nexus 私服,那么随后就需要对这个私服进行一些配置,因为这个私服需要连接外部的仓库(因为防火墙的原因,所以现在通过阿里云的镜像才可以快速访问)。

3.2 登录

  • 当 nexus 私服已经成功启动之后就可以进行配置操作了,但是如果要想配置,那么就应该进行登录控制了。

10.gif

  • 默认情况下,nexus 一般都会给一个 admin 的用户名,但是密码是随机生成的,如果要想知道当前随机生成的密码是多少,则必须通过 nexus 启动时提供的一个文件查看。
  • 查看当前的 nexus 密码:
  1. cat /usr/local/sonatype-work/nexus3/admin.password

11.png

本次的临时密码是 e464b505-daa4-47fc-a93c-e2d2ab7c9af9 。

  • 通过用户名和密码登录到 nexus 中。

12.gif

3.3 登录之后的配置

  • 第一次登录成功之后,nexus 会询问用户是否进行密码的修改,为了方便操作,本次的密码修改为 123456 。

13.gif

  • 之后,nexus 会询问用户是否允许匿名访问,即未授权的用户也可以直接使用,本次设置为允许。

14.png

  • 当全部配置完成之后,就会如下如下的界面:

15.png

3.4 仓库配置

  • 一切准备就绪后就可以进入到管理界面进行仓库的配置了,打开后台的仓库列表:

16.png

  • 在这里有如下的几个核心的重要仓库:
    • maven-central:中央仓库,是在整个 nexus 之中最为重要的一个配置仓库。
    • maven-public:公共仓库,所有仓库的配置合集。
    • maven-releases:存放所有 jar 文件的发布仓库。
    • maven-snapshots:保存所有仓库的快照。

3.5 代理仓库

  • 如果想使用 nexus ,那么首先就需要配置有一个国内的镜像代理仓库,本次使用的是阿里云的 maven 镜像,镜像的访问地址

17.png

  • 如果要进行配置,那么首先就需要在 nexus 控制台中创建一个新的仓库,仓库的类型为 proxy 仓库。

18.png

19.png

  • 随后输入代理仓库的相关配置信息,包括名称和访问路径。

20.png

21.png

22.png

  • 此时创建的代理仓库还不能完全生效,因为在整个的构建工具访问的时候一般都是通过 public 的仓库访问的,所以需要将当前配置的 aliyun-proxy 加入到 maven-public 仓库中,这样才能让代理仓库生效。

23.gif

3.6 项目使用私服

  • 如果要想在 Gradle 项目中使用当前配置的私服,有两种方式:
    • ① 直接修改项目本地缓存路径中的 init.gradle 配置文件(全局生效)。
    • ② 直接在项目中进行配置。
  • 本次为了通用性,可以考虑修改 erp 项目中的仓库配置。
  • 如果要进行本地 nexus 私服的配置,就需要有一个私服路径,这个仓库的访问路径是:
  1. http://192.168.65.100/repository/maven-public/

24.gif

  • 修改 erp 项目的 build.gradle 文件,不是子模块的 build.gradle 文件:
  1. apply from: 'dependencies.gradle'
  2. def env = System.getProperty('env') ?: 'dev'
  3. allprojects {
  4. apply plugin: 'idea'
  5. apply plugin: 'java'
  6. apply plugin: 'java-library'
  7. sourceCompatibility = project_jdk
  8. targetCompatibility = project_jdk
  9. group project_group
  10. version project_version
  11. }
  12. subprojects {
  13. repositories {
  14. maven { // 配置私服
  15. allowInsecureProtocol = true // 如果是 http ,请加入这个配置
  16. url 'http://192.168.65.100/repository/maven-public/'
  17. }
  18. maven {
  19. url 'https://maven.aliyun.com/repository/public/'
  20. }
  21. mavenCentral()
  22. }
  23. dependencies {
  24. testImplementation(
  25. libraries.'junit-jupiter'
  26. )
  27. implementation(
  28. libraries.'druid',
  29. libraries.'jstl'
  30. )
  31. }
  32. test {
  33. useJUnitPlatform()
  34. }
  35. sourceSets { // 建立源代码的目录集合
  36. main {
  37. java {
  38. srcDirs = ['src/main/java']
  39. }
  40. resources {
  41. srcDirs = ['src/main/resources', "src/main/profiles/${env}"]
  42. }
  43. }
  44. test {
  45. java {
  46. srcDirs = ['src/test/java']
  47. }
  48. resources {
  49. srcDirs = ['src/test/resources']
  50. }
  51. }
  52. }
  53. gradle.taskGraph.whenReady {
  54. tasks.each { task ->
  55. if (task.name.contains('test')) {
  56. task.enabled = true
  57. }
  58. }
  59. }
  60. task sourceJar(type: Jar, dependsOn: classes) {
  61. archiveClassifier.set 'sources'
  62. from sourceSets.main.allSource
  63. }
  64. task javaDocTask(type: Javadoc) {
  65. source sourceSets.main.allJava
  66. }
  67. tasks.withType(Javadoc) {
  68. options.encoding = "UTF-8"
  69. }
  70. tasks.withType(JavaCompile) {
  71. options.encoding = "UTF-8"
  72. }
  73. [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'
  74. task javaDocJar(type: Jar, dependsOn: javaDocTask) {
  75. archiveClassifier.set 'javadoc'
  76. from javaDocTask.destinationDir
  77. }
  78. artifacts {
  79. archives sourceJar
  80. archives javaDocJar
  81. }
  82. }
  83. project(':erp-web') {
  84. dependencies {
  85. compileOnly(
  86. libraries.'servlet',
  87. libraries.'jsp',
  88. )
  89. }
  90. gradle.taskGraph.whenReady {
  91. tasks.each { task ->
  92. if (task.name.contains('javaDoc')) {
  93. task.enabled = false
  94. }
  95. }
  96. }
  97. }
  98. project(':erp-service') {
  99. configurations {
  100. all.collect { configuration -> // 全局的排除设置
  101. configuration.exclude group: 'javax.servlet'
  102. configuration.exclude group: 'com.alibaba', module: 'druid'
  103. }
  104. }
  105. }

注意:你此时可能发现对项目执行了 gradle clean build,发现私服中没有对应的 jar 包,那么此时可以将 Gradle 本地缓存中的 init.gradle 文件暂时移除或改名。

25.gif

3.7 全局配置

  • 如果想让以上的仓库变为整个 Gradle 全局配置,则直接修改 Gradle 本地缓存路径中的 init.gradle 文件,文件内容如下:
  1. allprojects {
  2. repositories {
  3. maven {
  4. allowInsecureProtocol = true // 如果是 http ,请加入这个配置
  5. url 'http://192.168.65.100/repository/maven-public/'
  6. }
  7. }
  8. }
  • 在当前系统之中所创建的所有项目都会通过 init.gradle 配置的仓库进行所有依赖库的下载。

第四章:Gradle 项目发布

4.1 概述

  • 当有了 Gradle 的私服之后,就需要考虑发布和管理自己的项目代码,那么在这样的环境下,就需要创建有一个专属的私服发布仓库。

4.2 创建项目

  • 创建名为 erp 的 java 项目(略)。

4.2 创建仓库

  • 如果当前的项目需要进行发布管理,则一定要有一个可以负责接收所有上传程序的仓库,那么本次创建的仓库名称是 erp ,而创建的时候需要创建两类仓库,创建的仓库类型是 maven2(hosted) 类型的仓库。
  • ① 创建第一类仓库 erp-release ,保存所有最终发布的 *.jar 程序文件。

26.gif

  • ② 重复上面的操作,创建第二类仓库 erp-snapshot 快照仓库:

27.gif

4.3 中央仓库

  • 现在定义完成的全部仓库如果想使用,则需要将其追加到 maven-public 的中央仓库中。

28.gif

  • 之所以需要这样的配置,是为了方便其他的 Gradle 项目对当前这两个仓库的程序(由开发者自行提交的)进行下载。

4.4 配置用户

  • 如果要想进行代码的上传,那么一定要配置有相关的用户认证信息,此时就可以创建一个新的用户,本次创建的用户的账号和密码分别是 zhangsan / 123456。

29.gif

4.5 项目配置

  • 发布的仓库已经创建成功了,随后就可以在 erp 项目里面进行所有上传的配置,编辑 build.gradle 配置文件即可完成:
  1. plugins {
  2. id 'java' // 配置的是一个 Java 插件(Java 项目)
  3. id 'java-library'
  4. id 'maven-publish' // 必须配置 maven-publish 插件
  5. }
  6. group 'com.github.fairy.era' // 组织名称
  7. version '1.0' // 项目版本
  8. sourceCompatibility = 1.8
  9. targetCompatibility = 1.8
  10. dependencies { // 依赖管理
  11. /* junit 5 */
  12. testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.8.2'
  13. /* druid */
  14. implementation group: 'com.alibaba', name: 'druid', version: '1.2.8'
  15. }
  16. gradle.taskGraph.whenReady { // 在所有的操作准备好之后触发
  17. tasks.each { task ->
  18. if (task.name.contains('test')) { // 如果发现有 test 任务,就跳过
  19. task.enabled = true // 当前任务不执行
  20. }
  21. }
  22. }
  23. task sourceJar(type: Jar, dependsOn: classes) { // 定义一个源代码的打包任务,并依赖于 classes 这种 Gradle 内置的任务
  24. archiveClassifier.set 'sources' // 文件的分类
  25. from sourceSets.main.allSource // 所有源代码的读取路径
  26. }
  27. task javaDocTask(type: Javadoc) {
  28. source sourceSets.main.allJava // 定义所有的 Java 源代码的路径
  29. }
  30. tasks.withType(Javadoc) { // 文档生成一定要有乱码处理
  31. options.encoding = "UTF-8"
  32. }
  33. tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置
  34. options.encoding = "UTF-8"
  35. }
  36. task javaDocJar(type: Jar, dependsOn: javaDocTask) { // 先生成 javadoc,才可以打包
  37. archiveClassifier.set 'javadoc' // 文件的分类
  38. from javaDocTask.destinationDir // 通过 javaDocTask 任务中找到目标路径
  39. }
  40. artifacts { // 最终的打包操作任务
  41. archives sourceJar
  42. archives javaDocJar
  43. }
  44. publishing { // 进行上传的配置
  45. publications {
  46. maven(MavenPublication) {
  47. // 如果是war包填写components.web,如果是jar包填写components.java
  48. from components.java
  49. groupId = project.group
  50. artifactId = project.name
  51. version = project.version
  52. }
  53. }
  54. repositories {
  55. maven {
  56. allowInsecureProtocol = true
  57. // 指定要上传的maven私服仓库
  58. url = version.endsWith('SNAPSHOT') ? "http://192.168.65.100/repository/erp-snapshot/" : "http://192.168.65.100/repository/erp-release/"
  59. //认证用户和密码
  60. credentials {
  61. username 'zhangsan'
  62. password '123456'
  63. }
  64. }
  65. }
  66. }
  • 修改 gradle.properties,增加如下的配置:
  1. systemProp.org.gradle.internal.publish.checksums.insecure=true

4.6 项目发布

  • 直接通过 gradle 命令就可以实现项目的发布处理:
  1. gradle publish