随着SpringBoot
的流行,Web应用的打包方式也终于不再只是Tomcat+war
了。实际项目中应该没人用Dropwizard吧
目前来看常用的构建工具是Maven
或Gradle
,打包成war或jar,当然是针对SpringBoot项目
Readme
首先是pom
的这个地方,改成对应方式
1
| <packaging>war或jar</packaging>
|
然后是jar
包的启动方式
1
| nohup java -jar 'packageName.jar.original'>日志文件或/dev/null 2>&1 &
|
Maven
war
配置主类,继承SpringBootServletInitializer
1 2 3 4 5 6 7 8 9 10 11 12 13
| @SpringBootApplication public class Application extends SpringBootServletInitializer {
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); }
public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); }
}
|
修改pom文件,排除内嵌容器并用war插件打包一些常见文件(idea的锅)和可能要使用的本地jar
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
| //排除内嵌容器 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency>
//使用maven-war插件 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <webResources> <resource> <directory>${project.basedir}/lib</directory> <targetPath>/WEB-INF/lib</targetPath> <includes> <include>**/*.jar</include> </includes> </resource> <resource> <directory>${project.basedir}/src/main/java/</directory> <targetPath>/WEB-INF/classes</targetPath> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </webResources> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build>
|
当然这个时候配上tomcat7-maven上传插件更佳
jar
SpringBoot内嵌容器,可以很方便的打成一个可直接运行的jar包,使用其提供的插件即可打成一个fatjar
当然这样也没有什么可说的了,但是之所以用SpringBoot不仅是因为其配置简单,更是因为它也可以方便的分离依赖和代码每次上传只需要上传很少的一部分即可。不是我想折腾而是公司有时候网速实在太烂,3、40m的包可能要上传几分钟甚至经常失败
fatjar
1 2 3 4 5 6 7 8 9
| //使用spring-boot插件 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
|
分离依赖
mvn dependency:copy-dependencies -DoutputDirectory=target/lib
如上命令导出依赖到target/lib
,之后只有在第一次或依赖发生变化的时候上传lib文件夹,其它情况下只需要上传到jar的同级目录即可
pom里加上jar插件来生成不包含依赖的jar包,此时jar插件生成的文件应该是packageName.jar.original
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>${rootPkg}.Application</mainClass> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> </archive> <classesDirectory> </classesDirectory> </configuration> </plugin>
|
Gradle
war
war包基本同上,注意启用war插件,没什么可说的
jar
首先注意Gradle的脚本是按顺序执行的
相比Maven这里使用SSH
插件实现自动上传,详细可以看文档,很简单。下面省略了remote的配置
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
| task setlib(type: Copy) { into "${buildDir}/lib" from configurations.runtime doLast { ssh.run { session(remotes.master) { execute "if [ ! -d '${webPath}/lib' ]; then mkdir -p '${webPath}/lib'; fi", ignoreError: true put from: "${buildDir}/lib", into: webPath } } } }
task deploy { doLast { ssh.run { session(remotes.master) { put from: "${buildDir}/${packageName}.jar.original", into: webPath execute "kill `ps aux | grep '${packageName}' | grep -v 'grep' | awk '{print \$2}'`", ignoreError: true execute "sleep 2s", ignoreError: true execute("cd ${webPath} && nohup sh -c '( ( java -jar ${packageName}.jar.original ) & )'") { result -> println result } } } } }
def setPropActive(String active) { def props = getProps() props.setProperty("spring.profiles.active", active) new File("${projectDir}/src/main/resources/application.properties") .withWriter { writer -> props.store(writer, null) } } task active { doFirst { setPropActive(e) } }
jar { manifest { attributes 'Manifest-Version': project.version, 'Built-By': "You Name", 'Main-Class': project.group + '.Application', 'Class-Path': configurations.compile.collect { "lib/${it.name}" }.join(' ') } archiveName = "${packageName}.jar" destinationDir = file("${buildDir}") }
|