Sprnig Boot 之路[3]--打包成可运行的jar

专题简介

SpringBoot之路专题是一个记录本人在使用Spring和SpringBoot相关技术中所遇到的问题和要解决的问题。每用到一处知识点,就会把这处知识补充到Github一个对应的分支上。会以专题的方式,力争每一篇博客,由浅入深,把每个知识点讲解到实战级别,并且分析Spring源码。整个项目会以一个开发一个博客系统为最终目标,每一个分支都记录着一步一步搭建的过程。与大家分享,代码会同步发布到这里

简介

spring boot最大的特点之一,就是整个项目不需要像以前一样需要容器环境,需要一堆各种配置。SpringBoot的项目可以直接把所有需要的依赖以一个jar包的形式打包,而运行则直接一个java -jar命令即可。这大大简化了发布和部署的流程。也更加拥抱微服务、容器化、弹性扩容等等云计算时代的技术和概念。

使用maven打包

如果想要使用maven进行打包,并且可以直接使用java -jar XXX.jar来运行,如果你只有一个添加了@SpringBootApplication 的类,那么是不需要任何配置的。直接使用mvn package就可以打包出一个可运行的jar包。结果如下图:

mvn package结果

如果你有多个入口类

如果,你有多个添加了@SpringBootApplication注解的入口类,然后在运行mvn package时,会爆出如下的错误:


[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.604s
[INFO] Finished at: Mon Aug 15 18:14:25 CST 2016
[INFO] Final Memory: 22M/226M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.4.0.RELEASE:repackage (default) on project beenoisy-spring-boot-way: 
Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.4.0.RELEASE:
repackage failed: Unable to find a single main class from the following candidates 

[
com.beenoisy.springboot.way.BeenoisySpringBootWayApplication, 
com.beenoisy.springboot.way.TestConflict
] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.


大体的意思是告诉你,没办法找到唯一的一个入口类。

所以,需要在pom.xml文件中加入<start-class>配置:


    <properties>
        <start-class>com.beenoisy.springboot.way.BeenoisySpringBootWayApplication</start-class>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.7</java.version>
    </properties>

关于start-class,spring boot官方手册是这么说明的:

The plugin rewrites your manifest, and in particular it manages the Main-Class and Start-Class entries, so if the defaults don't work you have to configure those there (not in the jar plugin). The Main-Class in the manifest is actually controlled by the layout property of the boot plugin, e.g.

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


所以,当你的默认方式不好用的时候,在properties中,加入一个start-class的属性,用于告诉spring boot maven plugin哪个类是入口类即可。

# 运行
直接使用java -jar XXX.jar即可运行这个程序。

beenoisy-spring-boot-way BeeNoisy$ java -jar target/beenoisy-spring-boot-way-0.0.1-SNAPSHOT.jar

. ____ _ __ _ _
/\ / ' __ _ () __ __ _ \ \ \
( ( )_
_ | '_ | '| | ' / ` | \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
' |____| .
|| ||| |_, | / / / /
=========|
|==============|/=////
:: Spring Boot :: (v1.4.0.RELEASE)

2016-08-15 18:24:23.388 INFO 62643 --- [ main] c.b.s.w.BeenoisySpringBootWayApplication : Starting BeenoisySpringBootWayApplication v0.0.1-SNAPSHOT on bogon with PID 62643 (/Users/didi/IdeaProjects/beenoisy-spring-boot-way/target/beenoisy-spring-boot-way-0.0.1-SNAPSHOT.jar started by BeeNoisy in /Users/didi/IdeaProjects/beenoisy-spring-boot-way)
2016-08-15 18:24:23.406 INFO 62643 --- [ main] c.b.s.w.BeenoisySpringBootWayApplication : No active profile set, falling back to default profiles: default
2016-08-15 18:24:23.560 INFO 62643 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@b1a58a3: startup date [Mon Aug 15 18:24:23 CST 2016]; root of context hierarchy
2016-08-15 18:24:26.424 INFO 62643 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-08-15 18:24:26.453 INFO 62643 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2016-08-15 18:24:26.458 INFO 62643 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.4
2016-08-15 18:24:26.683 INFO 62643 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2016-08-15 18:24:26.685 INFO 62643 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3130 ms
2016-08-15 18:24:26.963 INFO 62643 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-08-15 18:24:26.978 INFO 62643 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/]
2016-08-15 18:24:26.979 INFO 62643 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/
]
2016-08-15 18:24:26.979 INFO 62643 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/]
2016-08-15 18:24:26.979 INFO 62643 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/
]
2016-08-15 18:24:27.517 INFO 62643 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@b1a58a3: startup date [Mon Aug 15 18:24:23 CST 2016]; root of context hierarchy
2016-08-15 18:24:27.658 INFO 62643 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String com.beenoisy.springboot.way.controller.IndexController.index()
2016-08-15 18:24:27.664 INFO 62643 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-08-15 18:24:27.665 INFO 62643 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-08-15 18:24:27.719 INFO 62643 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-08-15 18:24:27.720 INFO 62643 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/
] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-08-15 18:24:27.805 INFO 62643 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-08-15 18:24:28.019 INFO 62643 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-08-15 18:24:28.158 INFO 62643 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-08-15 18:24:28.167 INFO 62643 --- [ main] c.b.s.w.BeenoisySpringBootWayApplication : Started BeenoisySpringBootWayApplication in 6.152 seconds (JVM running for 6.955)


参考资料:
>http://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html
http://stackoverflow.com/questions/23217002/how-do-i-tell-spring-boot-which-main-class-to-use-for-the-executable-jar
http://docs.spring.io/spring-boot/docs/1.2.5.RELEASE/reference/html/getting-started-first-application.html#getting-started-first-application-executable-jar

推荐阅读更多精彩内容