前言
  • 先前发布boot项目的时候,改动一点东西,就需要将整个项目重新打包部署,十分不便,所以把依赖lib从项目分离出来,每次部署只需要发布代码即可。
步骤1,更换maven的jar打包插件
  • 先前使用的是spring-boot-maven-plugin插件打包,这个插件会将项目所有的依赖打入BOOT-INF/lib下,jar包十分庞大,所以将打包插件替换为原生的 maven-jar-plugin。其中addClasspath标签表示需要加入到类构建路径,classpathPrefix指定Class-Path依赖的前缀路径,classpath的值大概是这样:lib/xx.jar...
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>${maven.jar.plugin.version}</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.xxx.Start</mainClass>
                        </manifest>
                         <manifestEntries>
                            <Class-Path>./config/</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
步骤2,使用插件拷贝依赖到jar外面的lib目录
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>${maven.dependency.plugin.version}</version>
                <executions>
                    <execution>
                        <id>copy-lib</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                            <includeScope>compile</includeScope>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
步骤3: 在和jar包同级的目录下新建一个config目录,放入application.yml文件
  • 这里可能有小伙伴有疑问了,打包的jar里面不是应该有application.yml文件吗,这里为什么再放一份?
  • 这是因为boot读取配置有一个优先级,放在jar包外面config目录优先级最高,主要是便于从外部修改配置,而不是改jar包中的application.yml文件。优先级如下:
  • 当前目录的config目录下
  • 当前目录
  • classpath的config目录下
  • classpath的根目录
步骤4:注意一个依赖的
  • 笔者多次通过java -jar的方式启动项目总是报如下错误:
ClassNotFoundException: org.springframework.boot.SpringApplication
  • 后来发现是一个依赖的问题,snakeyaml是运行时依赖,和tomcat一样,如果依赖分离则环境里面必须要有这个jar包才能正常解析yml配置文件,这里我直接将其依赖,也可以配置maven-dependency-plugin的includeScope为runtime,这样就会把运行时依赖也打入lib文件夹中。
<dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.21</version>
        </dependency>
其他&总结
  • 上述插件的效果都能通过观察MANIFEST.MF文件发现。这个文件在jar包的META-INF目录下,参考下图:
  • 配置与依赖分离,主要依托于maven强大的插件,而分离第三方依赖使用的是maven-dependency-plugin插件,注意需要指定 prepare-package,这样在maven的package命令完成前就会进行依赖的分离,而配置文件的分离,主要在于这个标签,让我们能指定一个目录作为classpath。
  • 如果有其他问题加入--debug可以让你可以看到比较详细的启动日志
  • 命令行启动springboot时,可以动态指定属性配置,这里的优先级是最高的,如指定项目运行的端口,指定配置文件为info.ymm
nohup java  -jar $jar  --server.port=8981 --spring.config.name=info   > logs/info.out 2>&1 &