# spring-boot-demo **Repository Path**: jeffliu/spring-boot-demo ## Basic Information - **Project Name**: spring-boot-demo - **Description**: Spring Boot 示例 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2016-09-06 - **Last Updated**: 2024-08-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring Boot 快速创建 [TOC] ## 背景 Spring 官方网站本身使用 Spring 框架开发,随着功能以及业务逻辑的日益复杂,应用伴随着大量的 XML 配置文件以及复杂的 Bean 依赖关系。随着 Spring 3.0 的发布,Spring IO 团队逐渐摆脱 XML 配置文件,并且在开发过程中大量使用“约定优先配置”(convention over configuration)的思想来摆脱 Spring 框架中各类繁复纷杂的配置(即使是Java Config)。 Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,它本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。 同时它集成了大量常用的第三方库配置(例如Jackson, JDBC, Mongo, Redis, Mail等等)详情查阅 [SPRING INITIALIZR](https://start.spring.io/#) 或 [Github](https://github.com/spring-projects/spring-boot/blob/v1.4.0.RELEASE/spring-boot-dependencies/pom.xml),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用(out-of-the-box),大部分的 Spring Boot 应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。 ## Spring Boot 简介 Spring Boot 简化了基于 Spring 的应用开发, 你只需要"run"就能创建一个独立的,产品级别的 Spring 应用。 我们为 Spring 平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。多数 Spring Boot 应用只需要很少的 Spring 配置。 你可以使用 Spring Boot 创建 Java 应用,并使用 ```java -jar```启动它或采用传统的 war 部署方式。我们也提供了一个运行 "spring scripts" 的命令行工具。 主要的目标: - 为所有 Spring 开发提供一个更快普及的入门体验。 - 开箱即用,但通过覆盖默认设置即可快速按需改变。 - 提供一系列大型项目常用的非功能性特性,比如:内嵌服务器,安全,指标,健康检测,外部化配置。 - 绝对不需要生成代码和XML配置的要求。 ## 系统要求 默认情况下,Spring Boot 1.4.0.RELEASE 需要 Java 7 和 Spring Framework 4.3.2.RELEASE 或更高版本。 你可以在 Java 6 下使用Spring Boot,不过需要添加额外配置(不在此处讨论)。官方明确支持的构建工具有 Maven(3.2+)和Gradle(1.12+)。 注:尽管 Spring Boot 可以在 Java 6 或 Java 7 环境下使用,但建议尽可能使用 Java 8。 ## Servlet 容器 > * 下列内嵌容器支持开箱即用(out of the box): 名称 | Servlet版本| Java版本 :------------|:------------|:------------ Tomcat 8 |3.1 |Java 7+ Tomcat 7 |3.0 |Java 6+ Jetty 9.3 |3.1 |Java 8+ Jetty 9.2 |3.1 |Java 7+ Jetty 8 |3.0 |Java 6+ Undertow 1.3 |3.1 |Java 7+ > * 你也可以将Spring Boot应用部署到任何兼容Servlet 3.0+的容器。 ## 开始使用 ### 使用指南 - Java 7+ 推荐 Java 8。 - 使用支持依赖管理的构建工具,比如 Maven 或 Gradle。 - 尽可能使用多 module,除非非常明确项目只是示例、将来不需要拆分、底层不复用。 - 遵循“约定优先配置” ``` └── springboot-sample ├── code-generated │   ├── pom.xml │   └── src │      ├── main │      │   ├── java │      │   └── resources │      └── test │      ├── java │      └── resources ├── blank-web │   ├── META-INF │   ├── README.md │   ├── pom.xml │   └── src │      ├── main │      │   ├── groovy │      │   ├── java │      │   └── resources │      │   ├── application.yml │      │   ├── static │      │   └── templates │      └── test │      ├── groovy │      ├── java │      └── resources └── pom.xml ``` ``` └── springboot-sample ├── pom.xml └── src └── main    ├── java    └── resources    ├── application.yml    ├── static    └── templates ``` ### 编写一个简单的应用 #### Git 源代码放在开源中国的码云里,跟着示例做需要大家了解两个 git 的基本操作,会用 git 的请忽略。 下载源码 ```bash git clone https://git.oschina.net/jeffliu/spring-boot-demo.git ``` 切换分支,后续每个节点代码 tag 会用斜体字标注如 *Tag 1.0*,切换命令如下: ```bash git checkout 1.0 ``` #### 创建项目 现在各种 IDE 对 Spring Boot 的支持都已经比较友好了,比如 IntelliJ IDEA ![IntelliJ IDEA Spring Initializr](images/idea_spring_initializr1.png) ![IntelliJ IDEA Spring Initializr](images/idea_spring_initializr2.png) ![IntelliJ IDEA Spring Initializr](images/idea_spring_initializr3.png) ![IntelliJ IDEA Spring Initializr](images/idea_spring_initializr4.png) ![IntelliJ IDEA Spring Initializr](images/idea_spring_initializr5.png) ![IntelliJ IDEA Spring Initializr](images/idea_spring_initializr6.png) ![IntelliJ IDEA Spring Initializr](images/idea_spring_initializr7.png) 甚至通过命令行也可以,参考 https://github.com/spring-io/initializr ``` $ mkdir springboot-sample && cd springboot-sample $ curl https://start.spring.io/starter.tgz -d dependencies=web -d style=web -d name=springboot-sample | tar -xzvf - ``` 但是我们忠诚的长城防火墙会识别万恶的资本主义糖衣炮弹,扒下糖衣丢掉炮弹,然而长城防火墙并不那么智能,通常连糖衣也会被丢弃,所以小伙伴们想体验到 IDE 的便利操作,不是那么容易。好在 Spring Initializr 并不依赖 IDE,我们可以通过浏览器访问 [https://start.spring.io](https://start.spring.io)来获得。 ![Spring Initializr](images/start_spring_io.png) 配置相当简单,最后点击 Generate Project 按钮,下载项目文件 spring-boot-demo.zip。解压后得到项目目录结构如下: *Tag 1.0* ``` spring-boot-demo ├── .mvn │   └── wrapper │   ├── maven-wrapper.jar │   └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main │   ├── java │   │   └── com │   │   └── jusfoun │   │   └── SpringBootDemoApplication.java │   └── resources │   ├── application.properties │   ├── static │   └── templates └── test └── java └── com └── jusfoun └── SpringBootDemoApplicationTests.java 14 directories, 8 files ``` 创建的项目包含了安装 maven 的脚本,通常我们直接忽略它,可以删除掉这些有 mvn 的文件及文件夹。 查看项目依赖情况,可以看到,Spring Boot 默认已经为我们做了很多。 ``` ➜ spring-boot-demo mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building spring-boot-demo 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ spring-boot-demo --- [INFO] com.jusfoun:spring-boot-demo:jar:0.0.1-SNAPSHOT [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.4.0.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.4.0.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:1.4.0.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.4.0.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.4.0.RELEASE:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.1.7:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.1.7:compile [INFO] | | | +- org.slf4j:jcl-over-slf4j:jar:1.7.21:compile [INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.21:compile [INFO] | | | \- org.slf4j:log4j-over-slf4j:jar:1.7.21:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.17:runtime [INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.4.0.RELEASE:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.4:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.4:compile [INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.4:compile [INFO] | +- org.hibernate:hibernate-validator:jar:5.2.4.Final:compile [INFO] | | +- javax.validation:validation-api:jar:1.1.0.Final:compile [INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile [INFO] | | \- com.fasterxml:classmate:jar:1.3.1:compile [INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.1:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.1:compile [INFO] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.8.1:compile [INFO] | +- org.springframework:spring-web:jar:4.3.2.RELEASE:compile [INFO] | | +- org.springframework:spring-aop:jar:4.3.2.RELEASE:compile [INFO] | | +- org.springframework:spring-beans:jar:4.3.2.RELEASE:compile [INFO] | | \- org.springframework:spring-context:jar:4.3.2.RELEASE:compile [INFO] | \- org.springframework:spring-webmvc:jar:4.3.2.RELEASE:compile [INFO] | \- org.springframework:spring-expression:jar:4.3.2.RELEASE:compile [INFO] \- org.springframework.boot:spring-boot-starter-test:jar:1.4.0.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test:jar:1.4.0.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test-autoconfigure:jar:1.4.0.RELEASE:test [INFO] +- com.jayway.jsonpath:json-path:jar:2.2.0:test [INFO] | +- net.minidev:json-smart:jar:2.2.1:test [INFO] | | \- net.minidev:accessors-smart:jar:1.1:test [INFO] | | \- org.ow2.asm:asm:jar:5.0.3:test [INFO] | \- org.slf4j:slf4j-api:jar:1.7.21:compile [INFO] +- junit:junit:jar:4.12:test [INFO] +- org.assertj:assertj-core:jar:2.5.0:test [INFO] +- org.mockito:mockito-core:jar:1.10.19:test [INFO] | \- org.objenesis:objenesis:jar:2.1:test [INFO] +- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] +- org.hamcrest:hamcrest-library:jar:1.3:test [INFO] +- org.skyscreamer:jsonassert:jar:1.3.0:test [INFO] | \- org.json:json:jar:20140107:test [INFO] +- org.springframework:spring-core:jar:4.3.2.RELEASE:compile [INFO] \- org.springframework:spring-test:jar:4.3.2.RELEASE:test [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.787 s [INFO] Finished at: 2016-08-31T14:18:58+08:00 [INFO] Final Memory: 21M/309M [INFO] ------------------------------------------------------------------------ ``` 执行 ```mvn test -Dtest=SpringBootDemoApplicationTests```,在第一次执行时会下载相关依赖,然后就看到编译执行一气呵成,看到如下结果,说明一切正常。 ``` Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ``` 执行 ``` mvn spring-boot:run ```打开浏览器输入地址```http://localhost:8080```可以看到一个404错误页面。这仍然是正常的,因为项目中没有任何的 Controller 存在。 #### 完成一个 REST 服务接口 *Tag 2.0* 其实到现在为止还没有自己写过一行代码,也没有做很多的事情,就已经得到了一个可以正常执行的项目。不相信?不管你们信不信,反正我是信了。现在我们可以开工写代码了,先创建 package com.jusfoun.web.controller 写个 Controller ```java @RestController @RequestMapping("/api") public class RestfulController { @PostMapping("/greeting") public Map greeting(@RequestBody Map requestMap) { Map map = new HashMap<>(); map.put("name", requestMap.containsKey("name") ? requestMap.get("name") : "EveryOne"); map.put("greeting", "Hello"); return map; } } ``` 再给它写个单元测试 ```java @RunWith(SpringRunner.class) @SpringBootTest @WebAppConfiguration public class RestfulControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); } @Test public void testGreeting() throws Exception { Map map = new HashMap<>(); map.put("name", "九次方"); ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false); this.mockMvc.perform(post("/api/greeting").contentType(MediaType.APPLICATION_JSON_UTF8).content(mapper.writeValueAsString(map))) .andExpect(status().isOk()) .andExpect(content().string(containsString("Hello"))) .andDo(print()); } } ``` 然后执行```mvn test -Dtest=RestfulControllerTest```得到如下结果(截取) ``` MockHttpServletRequest: HTTP Method = POST Request URI = /api/greeting Parameters = {} Headers = {Content-Type=[application/json;charset=UTF-8]} Handler: Type = com.jusfoun.web.controller.RestfulController Method = public java.util.Map com.jusfoun.web.controller.RestfulController.greeting(java.util.Map) Async: Async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: Attributes = null MockHttpServletResponse: Status = 200 Error message = null Headers = {Content-Type=[application/json;charset=UTF-8]} Content type = application/json;charset=UTF-8 Body = {"greeting":"Hello","name":"九次方"} Forwarded URL = null Redirected URL = null Cookies = [] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.103 sec - in com.jusfoun.controller.RestfulControllerTest 2016-08-31 15:25:57.994 INFO 16750 --- [ Thread-1] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@7ef82753: startup date [Wed Aug 31 15:25:55 CST 2016]; root of context hierarchy Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ``` 到这里你们相信这个项目可以正常执行了吧!Body 就是 /api/greeting 这个 RESTful 接口返回的 JSON 字符串。 看看目录结构有什么变化?就增加了前边说的两个 Java 文件,没有更多了对不对? ``` spring-boot-demo ├── pom.xml └── src ├── main │   ├── java │   │   └── com │   │   └── jusfoun │   │   ├── SpringBootDemoApplication.java │   │   └── web │   │   └── controller │   │   └── RestfulController.java │   └── resources │   ├── application.properties │   ├── static │   └── templates └── test └── java └── com └── jusfoun ├── SpringBootDemoApplicationTests.java └── controller └── RestfulControllerTest.java ``` 如果我们执行```mvn package -Dmaven.test.skip=true```(打包并跳过测试类的编译执行)我们会在 target 目录下得到如 spring-boot-demo-0.0.1-SNAPSHOT.jar 的文件,我们可以通过命令```java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar```来执行它。有没有发现我们已经做了一个可以提供服务的微型的 RESTful WEB API?这一切就这么自然的发生了,如此的简单神奇! #### 完成一个简单的 WEB 界面 *Tag 3.0* OK! 目前为止我们还没有提供 WEB 界面,在创建页面之前,我们先来看看 Spring Boot 已经通过自动配置(auto-configuration) 支持的模板情况。 - FreeMarker - Groovy - Thymeleaf - Velocity (deprecated in 1.4) - Mustache 当你使用这些引擎的任何一种,并采用默认的配置,你的模板将会从src/main/resources/templates目录下自动加载。 如果可能的话应避免使用 JSPs, 因为当 Spring Boot 应用使用内嵌 servlet 容器时,对 JSP 的支持有一些限制。 - Tomcat 只支持 war ,不支持可执行的 jar。 - Jetty 只支持 war。 - Undertow 不支持 JSPs。 - 创建一个自定义的 error.jsp 页面不能覆盖默认的 error handling 视图。 好了,我们回来接着写我们的项目,我们就挑 Thymeleaf 来实现前端视图。 增加依赖 ```xml org.springframework.boot spring-boot-starter-thymeleaf ``` 追新及方便调试,我们将 application.properties 重命名为 application.yml 并增加如下内容 ``` spring: thymeleaf: cache: false ``` 创建 Controller ```java @Controller @RequestMapping("/") public class IndexController { @GetMapping("/") public String index(Model model) { model.addAttribute("greeting", "Hello"); model.addAttribute("name", "军火库"); model.addAttribute("date", new Date()); return "index"; } } ``` 创建页面,默认情况下请将所有标签关闭,否则 Thymeleaf 将会给你个 error。 ```html Thymeleaf Demo

Hello, EveryOne!

2016-08-31 16:32:16
``` 现在启动应用```mvn spring-boot:run```,打开浏览器访问```http://localhost:8080```,如果你没有看到“Hello, 军火库!”,你就该去墙角面壁反省了。 #### DataAccess ##### MyBatis *Tag 4.0* 引入依赖及 MyBatis Generator ```xml mysql mysql-connector-java org.mybatis.spring.boot mybatis-spring-boot-starter 1.1.1 org.mybatis.generator mybatis-generator-maven-plugin 1.3.4 true true false Generate MyBatis Artifacts generate ``` 创建 generatorConfig.xml 文件并配置,然后执行命令生成 MyBatis 模型及数据访问层代码。 ``` mvn mybatis-generator:generate ``` 正确执行后将 skip 设置为 true。 为了简化后续开发工作,引入了 BaseMapper 和 BaseService,对 MyBatis 自动生成的 Mapper 接口稍作修改 ```java public interface InformationMapper { } ``` 改成 ```java public interface InformationMapper extends BaseMapper { } ``` 再创建 InformationService ```java @Service public class InformationService extends BaseService { } ``` 到这里就可以写个单元测试验证一下了。 ```java @RunWith(SpringRunner.class) @SpringBootTest public class InformationServiceTest { @Autowired private InformationService informationService; @Test public void insert() { Information information = new Information(); information.setInformationTitle("九次方"); information.setInformationAuthor("大数据"); information.setInformationContent("军火库"); informationService.insertSelective(information); assertThat(information.getInformationId(), Matchers.notNullValue()); System.out.println(information); } @Test public void query() { List informationList = informationService.selectByExample(new InformationExample()); assertThat(informationList, Matchers.notNullValue()); informationList.forEach(System.out::println); } } ``` application.yml 文件里配置数据源和 MyBatis 配置 ```yaml spring: datasource: name: test username: root password: 12345678 driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/demo?allowMultiQueries=true&autoReconnect=true&characterEncoding=utf8&characterSetResults=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false initialize: true mybatis: mapper-locations: ['classpath*:com/jusfoun/mybatis/mapper/*.xml', 'classpath*:com/jusfoun/mybatis/manual/*.xml'] type-aliases-package: classpath*:com.jusfoun.core.model executor-type: BATCH config-location: 'classpath:mybatis-config.xml' ``` initialize 初次执行为 true,之后可以改成 false,否则每次启动都会使用 schema.sql 和 data.sql 初始化数据库。 增加 MyBatis 配置 Bean ```java @Configuration @MapperScan(basePackages = "com.jusfoun.core.dao.mapper") public class MybatisConfig { } ``` 现在可以执行 ```mvn test -Dtest=InformationServiceTest``` 单元测试进行验证。  ##### JPA *Tag 5.0* 引入 JPA 依赖 ```xml org.springframework.boot spring-boot-starter-data-jpa ``` 生成 Information Entity 类【我使用 IntelliJ IDEA 生成这里不作介绍,Eclipse 应该也有生成插件】,再写个简单的 Repository ```java public interface InformationRepository extends Repository { Page findAll(Pageable pageable); } ``` 再给 Repository 写个单元测试 ```java @RunWith(SpringRunner.class) @SpringBootTest public class InformationRepositoryTests { @Autowired private InformationRepository repository; @Test public void findsFirstPageOfCities() { Page informations = this.repository.findAll(new PageRequest(0, 10)); assertThat(informations.getTotalElements()).isGreaterThan(0L); informations.getContent().forEach(System.out::println); } } ``` 现在可以执行 ```mvn test -Dtest=InformationRepositoryTests``` 单元测试进行验证。  可以看到 Spring Boot 使用起来相当简单,几乎不用加什么配置的,开发人员将更多的精力放到业务实现上。当然这只是在研发阶段,正式发布的时候,数据源是不能这么配的,尤其是使用 MySQL 的情况下。 ## 更多的一些 ### WEB 静态内容 默认情况下,Spring Boot 从 classpath 下一个叫 /static(/public,/resources或/META-INF/resources)的文件夹或从 ServletContext 根目录提供静态内容。这使用了 Spring MVC 的 ResourceHttpRequestHandler, 所以你可以通过添加自己的 WebMvcConfigurerAdapter 并覆写 addResourceHandlers 方法来改变这个行为(加载静态文件)。 在一个单独的 web 应用中,容器默认的 servlet 是开启的,如果 Spring 决定不处理某些请求,默认的 servlet 作为一个回退(降级)将从 ServletContext 根目录加载内容。大多数时候,这不会发生(除非你修改默认的 MVC 配置),因为 Spring 总能够通过 DispatcherServlet 处理请求。 此外,上述标准的静态资源位置有个例外情况是 Webjars 内容。任何在 /webjars/** 路径下的资源都将从 jar 文件中提供,只要它们以 Webjars 的格式打包。 注:如果你的应用将被打包成 jar,那就不要使用 src/main/webapp 文件夹。尽管该文件夹是一个共同的标准,但它仅在打包成 war 的情况下起作用,并且如果产生一个 jar,多数构建工具都会静悄悄的忽略它。 默认支持的 MIME 如下,如果不在此列的就需要自定义了,也比较方便,后边给示例。 ``` abs, ai, aif, aifc, aiff, aim, art, asf, asx, au, avi, avx, bcpio, bin, bmp, body, cdf, cer, class, cpio, csh, css, dib, doc, dtd, dv, dvi, eps, etx, exe, gif, gtar, gz, hdf, hqx, htc, htm, html, ief, jad, jar, java, jnlp, jpe, jpeg, jpg, js, jsf, json, jspf, kar, latex, m3u, mac, man, mathml, me, mid, midi, mif, mov, movie, mp1, mp2, mp3, mp4, mpa, mpe, mpeg, mpega, mpg, mpv2, ms, nc, oda, odb, odc, odf, odg, odi, odm, odp, ods, odt, otg, oth, otp, ots, ott, ogx, ogv, oga, ogg, spx, flac, anx, axa, axv, xspf, pbm, pct, pdf, pgm, pic, pict, pls, png, pnm, pnt, ppm, ppt, pps, ps, psd, qt, qti, qtif, ras, rdf, rgb, rm, roff, rtf, rtx, sh, shar, sit, snd, src, sv4cpio, sv4crc, svg, svgz, swf, t, tar, tcl, tex, texi, texinfo, tif, tiff, tr, tsv, txt, ulw, ustar, vxml, xbm, xht, xhtml, xls, xml, xpm, xsl, xslt, xul, xwd, vsd, wav, wbmp, wml, wmlc, wmls, wmlscriptc, wmv, wrl, wspolicy, z, zip ``` #### xlsx 文件下载示例 比如项目中需要提供静态的 xlsx 文件下载功能,如果直接放在项目中,在打包成可执行 jar 以后默认是无法下载的,我们可以通过以下几步设置,搞定它。 ```java @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 绝对路径需要加上file: 前缀 registry.addResourceHandler("/download/**") .addResourceLocations("file:/Users/liutiyang/Downloads/"); registry.addResourceHandler("/file/**") .addResourceLocations("classpath:/files/") .setCachePeriod(3600) .resourceChain(true) .addResolver(new GzipResourceResolver()) .addResolver(new PathResourceResolver()); } } @Configuration public class CustomizerMimeMapper implements EmbeddedServletContainerCustomizer { @Override public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) { MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT); mappings.add("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); configurableEmbeddedServletContainer.setMimeMappings(mappings); } } ``` 有了这两个 configuration 就可以从 WEB 端访问或下载 /Users/liutiyang/Downloads/ 和 resources/files/ 下的文件了。访问地址分别是```http://localhost:8080/download/filename.xlsx```, ```http://localhost:8080/file/filename.xlsx```。 ### 第三方支持 Spring Boot 提供了很多开箱即用的自动配置特性(或简单配置,比如连接数据库等外部资源时),可从 http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter 看到,比较多,就不再一一罗列。 比如我们在之前项目中已经使用的 - spring-boot-starter-web - spring-boot-starter-test - spring-boot-starter-thymeleaf ### profiles 和外部配置 ```yaml spring: profiles: active: development --- spring: profiles: development thymeleaf: cache: false server: port: 8080 --- spring: profiles: test thymeleaf: cache: true server: port: 9080 --- spring: profiles: production thymeleaf: cache: true server: port: 80 ``` 启动时默认使用 development 配置,如下命令启动可以激活 test 配置 ```bash java -jar -Dspring.profiles.active=test spring-boot-demo-0.0.1-SNAPSHOT.jar ``` 当然,Spring Boot 允许外化(externalize)你的配置,这样你能够在不同的环境下使用相同的代码。你可以使用 properties 文件,YAML 文件,环境变量和命令行参数来外化配置。使用@Value注解,可以直接将属性值注入到你的 beans 中,并通过 Spring 的 Environment 抽象或绑定到结构化对象来访问。 Spring Boot 使用一个非常特别的 PropertySource 次序来允许对值进行合理的覆盖,需要以下面的次序考虑属性,优先级自上而下逐级递减: 1. 命令行参数 1. 来自于 java:comp/env 的JNDI属性 1. Java 系统属性(System.getProperties()) 1. 操作系统环境变量 1. 只有在 random.* 里包含的属性会产生一个 RandomValuePropertySource 1. 在打包的 jar 外的应用程序配置文件(application.properties,包含 YAML 和 profile 变量) 1. 在 @Configuration 类上的 @PropertySource 注解 1. 默认属性(使用 SpringApplication.setDefaultProperties 指定) 例如:我们还可以通过参数改变配置文件 ```bash java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar –-spring.config.location=file:/etc/spring/boot.yml ``` 这样就可以用 boot.yml 的配置覆盖 jar 里边的配置信息。 *这里有个坑,spring.config.location 一定要放在 jar 文件之后* ### Unix/Linux services http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html ```xml org.springframework.boot spring-boot-maven-plugin true ``` 然后 package 得到可执行 jar,这个 jar 可以非常简单的加入到 Unix/Linux services 使用 init.d 或者 systemd。 ```bash $ sudo ln -s /opt/spring_boot/spring-boot-demo.jar /etc/init.d/spring-boot-demo $ service spring-boot-demo start # 产生日志文件 /var/logs/spring-boot-demo.log ``` 利用 chkconfig 命令配置开机启动。 如果需要外部配置或启动参数,在 jar 同一目录创建和 jar 同名的 conf 文件 例如```spring-boot-demo.conf``` 内容如下(按需修改): ```conf JAVA_OPTS="-Xms4096m -Xmx8192m -Dspring.profiles.active=production" ``` ```bash $ chmod 400 spring-boot-demo.conf $ service spring-boot-demo start ``` ## 结束语 Spring Boot 的特性非常多,这里只是介绍了很少的一部分,因为篇幅和时间问题,这次就不再介绍更多的内容了,如果大家有疑问或者想了解更多的东西,欢迎大家来找我讨论,共同学习,共同进步,谢谢! ## 参考资料 http://docs.spring.io/spring-boot/docs/current/reference/html/index.html https://github.com/spring-projects/spring-boot/tree/v1.4.0.RELEASE/spring-boot-samples