SpringBoot项目打包瘦身

1.前言

      传统项目,还处于使用很老的技术,比如一个war包打天下,前后端的代码都在一个项目中就会导致时间越久远之后,这个项目的代码的体积量越来越大,最后打出来的包越越来越大,各种依赖混乱,依赖冲突的情况出现,每次代码改动一点部署都要打一个很大的jar/war包丢到服务器上,如果服务器的网络很差,上传这个待发布的包就会很慢很慢,从而让开发者,发布者渐渐的感到心力憔悴,这种人肉半自动化的发布在未来也会被淘汰掉,随之而来的就是更加好用的CI/CD,持续集成持续构建发布的全自动化方案,全程只靠点一点,一点轻松搞定。

      随着技术的不断进步,我们大java的生态圈是越来越繁荣,技术栈也越来越全,一站式解决方案也是很yyds的,就比如说Spring/springBoot/SpringCloud等,说白了就是这些技术栈解放了开发者的双手,提高了开发者对各种繁琐的配置,也提高了开发者的代码产出效率,让开发者更加的专注于业务本身,所以我就做了一个这样的实践。

2.项目pom配置

<build>
      <!--
特别注意:
项目仅仅是为了演示配置方便,直接在parent的build部分做了插件配置和运行定义。
但是实际项目中需要把这些定义只放到spring boot模块项目(可优化使用pluginManagement形式),避免干扰其他util、common等模块项目
-->
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
               <!-- 不打包资源文件-->
               <excludes>
                  <exclude>static/**</exclude>
                  <exclude>*.properties</exclude>
                  <exclude>*.xml</exclude>
                  <exclude>*.json</exclude>
                  <exclude>*.yaml</exclude>
                  <exclude>*.yml</exclude>
                  <exclude>*.png</exclude>
                  <exclude>*.txt</exclude>
               </excludes>
               <archive>
                  <!--  &lt;!&ndash; 生成的jar中,不要包含pom.xml和pom.properties这两个文件 &ndash;&gt;-->
                  <addMavenDescriptor>false</addMavenDescriptor>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <!--MANIFEST.MF中的Class-Path加前缀-->
                     <classpathPrefix>lib/</classpathPrefix>
                     <!--jar不包含唯一版本-->
                     <useUniqueVersions>false</useUniqueVersions>
                     <!-- 项目启动类 -->
                     <mainClass>com.dyyy.wechat.integration.web.WechatIntegrationWebApplication</mainClass>
                     <!--<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>-->
                  </manifest>
                  <manifestEntries>
                     <!-- &lt;!&ndash;
                             有些非官方三方的诸如sdk jar在pom中是以systemPath方式引入的,maven-jar-plugin组件没有直接参数声明包含指定scope的组件
                             通过使用额外定义 Class-Path 值来追加指定依赖组件列表,在子模块按实际情况指定 jar-manifestEntries-classpath 值即可
                             例如(注意前面个点字符及各空格分隔符):. lib/xxx-1.0.0.jar lib/yyy-2.0.0.jar
                             详见各子模块中 boot-jar-output 属性定义示例
                             &ndash;&gt;-->
                     <Class-Path>./resources/</Class-Path>
                  </manifestEntries>
               </archive>
               <outputDirectory>${project.build.directory}</outputDirectory>
            </configuration>
         </plugin>
         <!-- 拷贝项目所有依赖jar文件到构建lib目录下 -->
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
               <execution>
                  <id>copy-dependencies</id>
                  <phase>package</phase>
                  <goals>
                     <goal>copy-dependencies</goal>
                  </goals>
                  <configuration>
                     <!--
                            各子模块按照实际层级定义各模块对应的属性值,检查所有微服务模块依赖jar文件合并复制到同一个目录
                            详见各子模块中 boot-jar-output 属性定义
                            -->
                     <outputDirectory>${project.build.directory}/lib/</outputDirectory>
                     <!--<excludeTransitive>false</excludeTransitive>
                            <stripVersion>false</stripVersion>
                            <silent>false</silent>
                            <includeScope>runtime</includeScope>-->
                  </configuration>
               </execution>
            </executions>
         </plugin>
         <!--拷贝资源文件-->
         <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <executions>
               <execution>
                  <id>copy-resources</id>
                  <phase>package</phase>
                  <goals>
                     <goal>copy-resources</goal>
                  </goals>
                  <configuration>
                     <resources>
                        <resource>
                           <directory>src/main/resources</directory>
                        </resource>
                     </resources>
                     <outputDirectory>${project.build.directory}/resources</outputDirectory>
                  </configuration>
               </execution>
            </executions>
         </plugin>
         <!--Spring Boot模块jar构建-->
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
               <mainClass>xxx.xxx.Starter(项目的主类的全路径名--包名.类名)</mainClass>
               <classifier>exec</classifier>
               <includeSystemScope>true</includeSystemScope>
               <includes>
                  <!-- 不存在的include引用,相当于排除所有maven依赖jar,没有任何三方jar文件打入输出jar-->
                  <include>
                     <groupId>null</groupId>
                     <artifactId>null</artifactId>
                  </include>
                  <!--<include>
                            <groupId>*</groupId>
                            <artifactId>*-dto</artifactId>
                        </include>-->
               </includes>
               <layout>ZIP</layout>
               <addResources>true</addResources>
               <!--
                    基于maven-jar-plugin输出微服务jar文件进行二次spring boot重新打包文件的输出目录
                    所有微服务构建输出jar文件统一输出到与lib同一个目录,便于共同引用同一个lib目录
                    详见各子模块中boot-jar-output属性定义
                    -->
               <outputDirectory>${project.build.directory}</outputDirectory>
               <skip>true</skip>
            </configuration>
            <executions>
               <execution>
                  <goals>
                     <goal>repackage</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
         <!-- 跳过deploy -->
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <version>2.8.2</version>
            <configuration>
               <skip>true</skip>
            </configuration>
         </plugin>

      </plugins>
   </build>

3.打包

       SpringBoot项目的pom文件配置好了之后就可以点击idea右侧的maven的package按钮,然后在idea左侧的target目录下有三个文件,下一步需要将这几个文件拷贝到项目发布的服务路径下:

 4.发布

       由于我的这个项目是微服务项目,采用nacos作为注册中心,所以一些公共的配置是放在注册中心的,所以当时我在我本机的电脑上创建了一个JAR的目录,同时我的电脑上装有JDK的环境,所以下面可以正常的把项目跑起来,

将该项目在nacos中的配置文件拷贝一份放入JAR路径中的application,yml中

将打包路径下的lib、resources和jar包拷贝到发布路径下:打出的jar只有37kb 

 在本机的JAR路径下运行项目:

java -Dfile.encoding=utf-8   -jar  xxxxxx-SNAPSHOT.jar --spring.profiles.active=uat

5.遇到的问题及解决办法

5.1pom配置和启动参数指定有误导致如下:

 解决:

这个地方配置为true就会报这个错,启动不用指定:-Djava.ext.dirs -Dloader.path  -Dloader.path等配置参数,使用4中的运行命令直接回车即可。 

 5.2启动找不到主类

pom配置如下:

5.3引入项目中的第三方jar打包 

 6.总结优化建议

上面拷贝发布的环节可以借助编写dockerfile构建项目镜像,然后使用jenkins编写构建流水线脚本构建项目,在借助私有hub仓库,每次构建的镜像都会推送到Hub私服上,然后使用K8S来管理容器,在有兴趣的话可以使用一款K8S的管理工具或平台,就不用每次去服务的黑窗口下使用K8S的命令来jenkins构建好的待发布项目了,到此是不是我们会有一个清晰连贯的思路和突发奇想的灵感了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值