pom文件及maven、docker笔记

2020-01-02  本文已影响0人  榷奕

1. pom内容

pom文件一打开,有这么几个大块的分组:

(1)dependency

dependency内部通过groupId,artufactId以及version确定唯一的依赖
groupId: 组织的唯一标识。
artifactId: 项目的唯一标识。
version:项目的版本。

(2)properties
应该是自定义的属性值,为了在pom的其他地方引用这些properties
<properties>
    <mysql.version>5.1.1</mysql.version>
</properties>
(3)编译插件plugin

2. spring-boot-maven-plugin

(1) 如果你的POM是继承spring-boot-starter-parent的话,只需要下面的指定就行。

<properties>
    <!-- The main class to start by executing java -jar -->
    <start-class>com.mycorp.starter.HelloWorldApplication</start-class>
</properties>

(2)如果你的POM不是继承spring-boot-starter-parent的话,需要下面的指定。

    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>1.3.5.RELEASE</version>
      <configuration>
        <mainClass>${start-class}</mainClass>
        <layout>ZIP</layout>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>repackage</goal>
          </goals>
        </execution>
      </executions>
    </plugin>

上面这两种情况的原理,是由于你引入了<parent>,然后springboot的parent在build的子标签里面有pluginManagement,已经把springboot-maven-plugin这个插件的很多都写出来了,唯一就是引用了一个${start-class},所以你补上就行。
如果没继承这个parent,那么写出来的跟抄这个parent下面是一样的。
(这里又涉及到另一个只是,只要是pom里面的Maganement,无论是dependencyManagement还是pluginManagement,都是在父工程里面用的,在父工程里面用了之后,子工程直接继承,所以你多半不会自己去主动定义。)

                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <mainClass>${start-class}</mainClass>
                    </configuration>
                </plugin>

execution是一个执行任务,configuration是这个任务能用到的参数,有一些configuration是plugin用的,有一些是execution用的,反正都是框架定义好的参数,你只要传递就行了。
execution里面有用的只有一个goal,goal应该只会需要repackage模式,经过了这个repackage之后,打出来的包才有两个,一个是.original,一个是.jar,maven第一次打出来的包再次打包的时候变成了.original,然后第二次打包结果变成.jar。从体积上来计算,.original是几百k,源代码也是几百k,而.jar是几十兆,应该是一个胖包一个瘦包,再次打包的过程把所有的依赖都打进去了。

3. docker-maven-plugin

思路:首先知道根据dockerfile是怎么打包的,
这里开始解析dockerfile里面的每一句,
然后把dockerfile变成pom里面的<>。

(1) dockerfile内容
#父镜像
FROM java:8
#拷贝jar包
ADD scm.jar app.jar
#暴露接口
EXPOSE 8080
#启动容器的时候运行jar包
ENTRYPOINT [ "java", "-jar", "/app.jar" ]

如果真写起来dockerfile的话,上面应该就够用了。
dockerfile里面的四句话,父镜像,添加jar,运行jar,-p暴露端口。
(要调研的应该也就是Add和Entrypoint这两个有什么区别,或者不调研了)
Copy和Add用法好像一样的,都是Copy/Add + 要复制的jar + 别名

(2)使用dockefile结合插件
<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <!--使用docker-maven-plugin插件-->
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.0.0</version>

            <!--将插件绑定在某个phase执行,下面的这个execution发挥的作用就是把这个docker打包镜像的过程绑定到了maven-plugin上面去-->
            <executions>
                <execution>
                    <id>build-image</id>
                    <!--用户只需执行mvn package ,就会自动执行mvn docker:build-->
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>

            <configuration>
                <!--指定生成的镜像名-->
                <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                <!--指定标签-->
                <imageTags>
                    <imageTag>latest</imageTag>
                </imageTags>
                <!-- 指定 Dockerfile 路径-->
                <dockerDirectory>${project.basedir}</dockerDirectory>
                <!--指定远程 docker api地址-->
                <dockerHost>http://10.112.158.59:2375</dockerHost>

                <!-- 这里是复制 jar 包到 docker 容器指定目录配置,相当于dockerfile里面的那句Add -->
                <resources>
                    <resource>
                        <targetPath>/</targetPath>
                        <!--需要复制的jar 包所在的路径  此处配置的 即对应 target 目录,这个表达式你背下来就行了不用变-->
                        <directory>${project.build.directory}</directory>
                        <!-- 需要复制的 jar包 ,这里对应的是 Dockerfile中添加的文件名,也是背下来就行了 -->
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
        </plugin>
    </plugins>
</build>
(3) 完全使用pom文件

这个是结合上面的那一份代码,改动了其中的dockerfile的那一句,变成了另外三句(其中的copy语句是下面的resource)。
以及下面这份文档应该是可以直接复制的,除了中间有服务器地址和端口号两个之外感觉别的都不用变。

<build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>


            <!-- 跳过单元测试 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>

            <!--使用docker-maven-plugin插件-->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <!--将插件绑定在某个phase执行-->
                <executions>
                    <execution>
                        <id>build-image</id>
                        <!--用户只需执行mvn package ,就会自动执行mvn docker:build-->
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>

                <configuration>
<!--                    这里是生成dockerfile的,也就是不需要自己写dockerfile了,直接在这个pom里面定义!!!!流弊!!!
                           dockerfile里面的每一行在这里面都有一个标签名<>对应着-->
                    <!--指定生成的镜像名,这里注意docker生成文件的前缀,在上面要有一个properties来定义这个前缀-->
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <!--指定标签-->
                    <imageTags>
                        <imageTag>latest</imageTag>
                    </imageTags>
                    <!--指定远程 docker api地址(!!!这里要变化)-->
                    <dockerHost>http://10.112.158.59:2375</dockerHost>

                    <!-- 指定 Dockerfile 路径-->
<!--                    <dockerDirectory>${project.basedir}</dockerDirectory>-->

                    <!-- 从这里开始是重点了-->
                    <baseImage>java:8</baseImage>
                    <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
                    <exposes>
                        <!--(!!!)这个暴露接口也要变化 -->
                        <expose>7050</expose>
                    </exposes>

                    <!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <!--jar 包所在的路径  此处配置的 即对应 target 目录-->
                            <directory>${project.build.directory}</directory>
                            <!-- 需要包含的 jar包 ,这里对应的是 Dockerfile中添加的文件名 -->
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>

            </plugin>
        </plugins>
    </build>
(4) 生成镜像之后是要用下面的视图来启动容器的

至于这个视图启动容器看着就简单,就不写了。

4. maven

(1) maven项目结构

构建打包技术,发展历史是make -> ant -> maven -> gradle

maven工程中各目录结构含义

也就是说现在的工程就是一个maven工程,所以现在的src、pom、resource什么的全都是由这个maven工程来决定的,这是maven的约定,让maven知道什么的东西放在哪里,然后可以自动化构建。、

(2)maven依赖

首先是依赖的排除,一定是一个很大的依赖,里面一堆二级子依赖,然后这里面的一堆想排除哪个哪个,在这个大依赖的标签下面写排除。

<dependency>
     <exclusion>

然后是依赖冲突,如果对于一个依赖的好几个版本都声明了,两个原则。首先是路径最短的优先,你直接引用是要比在别的大包里面带进来要优先的;如果路径一样,先声明的优先,如果都是大包带进来的,那么排在上面的优先。

最后是统一管理依赖的版本。原理大概就是在pom里面的<properties>里面声明各种自定义属性,然后在下面引用dependency的时候,在version里面用${}来引用上面定义的属性。应该是应用于一个体系的框架内的所有引用,比如spring框架的很多东西,把这些所有与spring相关的引用版本保持一致。

(3) maven生命周期

所以总结,最终在idea上的mvn插件里面有用的仍然只有一个clean和package。
以及maven的常用命令,mvn开头的那几个Linux命令,完完全全就对应了上面的这几个指令,clean、test、package什么的。

(4) maven的坐标

跟上面的maven依赖联系起来。

所有的maven项目都要有上面的三个坐标,三个加起来就在仓库里面唯一确定了这个依赖。dependency引用的时候也是用这三个加起来就能指定到底引用哪一个项目,所以dependency下面有用的也是这三个。

(5)继承 <parent>

这个是为了在一个父工程里面统一管理依赖版本的。
用处就是在父工程里面定义一个<dependencyManagement>,在这里面定义各种<dependency>,写上版本号。
再之后在子工程里面继承这个parent,子工程里面再引用各种dependency的时候就可以不写版号了。
(这个parent不能给子工程引入依赖,只是对依赖版本version的统一管理)

(6)聚合 <module>

module这个,如果聚合起来了的话,从parent入口那里可以直接把所有的项目一键打包并且复制到本机的Tomcat,所有工程的一键部署吧(学了之后感觉没卵用)

(7)依赖作用范围<scope>

这个就是表示这个依赖会在哪里起作用,会不会进入最终的jar包吧,如果不配置默认是打进jar包的。

上一篇 下一篇

猜你喜欢

热点阅读