spring boot学习1

转:https://blog.csdn.net/jsyxcjw/article/details/46763639

1 开始

1.1 spring介绍

Spring Boot使开发独立的,产品级别的基于Spring的应用变得很是简单,你只需"just run"。 咱们为Spring平台及第三方库提供开箱即用的设置,这样你就能够有条不紊地开始。多数Spring Boot应用须要不多的Spring配置。javascript

你可使用Spring Boot建立Java应用,并使用java -jar启动它或采用传统的war部署方式。php

1.2 系统要求

默认状况下,Spring Boot 1.3.0.BUILD-SNAPSHOT 须要Java7和Spring框架4.1.3或以上。你能够在Java6下使用Spring Boot,不过须要添加额外配置。具体参考Section 73.9, “How to use Java 6” 。构建环境明确支持的有Maven(3.2+)和Gradle(1.12+)。css

Servlet容器 下列内嵌容器支持开箱即用(out of the box):html

  1.  
    名称 Servlet版本 Java版本
  2.  
    Tomcat 8 3.1 Java 7+
  3.  
    Tomcat 7 3.0 Java 6+
  4.  
    Jetty 9 3.1 Java 7+
  5.  
    Jetty 8 3.0 Java 6+
  6.  
    Undertow 1.1 3.1 Java 7+

你也能够将Spring Boot应用部署到任何兼容Servlet 3.0+的容器。java

1.3 第一个spring boot应用

在开始前,你须要打开一个终端,检查是否安装可用的Java版本和Maven:web

  1.  
    $ mvn -v
  2.  
    Apache Maven 3.2.3 (33f8c3e1027c3ddde99d3cdebad2656a31e8fdf4; 2014-08-11T13:58:10-07:00)
  3.  
    Maven home: /Users/user/tools/apache-maven -3.1.1
  4.  
    Java version: 1.7.0_51, vendor: Oracle Corporation

建立pom.xml文件算法

  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.  
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.  
    <modelVersion>4.0.0</modelVersion>
  5.  
     
  6.  
    <groupId>com.example</groupId>
  7.  
    <artifactId>myproject</artifactId>
  8.  
    <version>0.0.1-SNAPSHOT</version>
  9.  
     
  10.  
    <parent>
  11.  
    <groupId>org.springframework.boot</groupId>
  12.  
    <artifactId>spring-boot-starter-parent</artifactId>
  13.  
    <version>1.3.0.BUILD-SNAPSHOT</version>
  14.  
    </parent>
  15.  
     
  16.  
    <!-- Additional lines to be added here... -->
  17.  
     
  18.  
    <!-- (you don't need this if you are using a .RELEASE version) -->
  19.  
    <repositories>
  20.  
    <repository>
  21.  
    <id>spring-snapshots</id>
  22.  
    <url>http://repo.spring.io/snapshot</url>
  23.  
    <snapshots><enabled>true</enabled></snapshots>
  24.  
    </repository>
  25.  
    <repository>
  26.  
    <id>spring-milestones</id>
  27.  
    <url>http://repo.spring.io/milestone</url>
  28.  
    </repository>
  29.  
    </repositories>
  30.  
    <pluginRepositories>
  31.  
    <pluginRepository>
  32.  
    <id>spring-snapshots</id>
  33.  
    <url>http://repo.spring.io/snapshot</url>
  34.  
    </pluginRepository>
  35.  
    <pluginRepository>
  36.  
    <id>spring-milestones</id>
  37.  
    <url>http://repo.spring.io/milestone</url>
  38.  
    </pluginRepository>
  39.  
    </pluginRepositories>
  40.  
    </project>

添加classpath依赖:spring

Spring Boot提供不少"Starter POMs",这可以让你轻松的将jars添加到你的classpath下。咱们的示例程序已经在POM的partent节点使用了spring-boot-starter-parent。spring-boot-starter-parent是一个特殊的starter,它提供了有用的Maven默认设置。同时,它也提供了一个dependency-management节点,这样对于”blessed“依赖你能够省略version标记。sql

  1.  
    <dependencies>
  2.  
    <dependency>
  3.  
    <groupId>org.springframework.boot</groupId>
  4.  
    <artifactId>spring-boot-starter-web</artifactId>
  5.  
    </dependency>
  6.  
    </dependencies>

若是再次运行mvn dependency:tree,你将看到如今有了一些其余依赖,包括Tomcat web服务器和Spring Boot自身。数据库

编写代码:

为了完成应用程序,咱们须要建立一个单独的Java文件。Maven默认会编译src/main/java下的源码,因此你须要建立那样的文件结构,而后添加一个名为src/main/java/Example.java的文件:

  1.  
    import org.springframework.boot.*;
  2.  
    import org.springframework.boot.autoconfigure.*;
  3.  
    import org.springframework.stereotype.*;
  4.  
    import org.springframework.web.bind.annotation.*;
  5.  
     
  6.  
    @RestController
  7.  
    @EnableAutoConfiguration
  8.  
    public class Example {
  9.  
     
  10.  
    @RequestMapping("/")
  11.  
    String home() {
  12.  
    return "Hello World!";
  13.  
    }
  14.  
     
  15.  
    public static void main(String[] args) throws Exception {
  16.  
    SpringApplication.run(Example.class, args);
  17.  
    }
  18.  
    }

@RestController和@RequestMapping说明:

@RestController。这被称为一个构造型(stereotype)注解。它为阅读代码的人们提供建议。对于Spring,该类扮演了一个特殊角色。在本示例中,咱们的类是一个web @Controller,因此当处理进来的web请求时,Spring会询问它。

@RequestMapping注解提供路由信息。它告诉Spring任何来自"/"路径的HTTP请求都应该被映射到home方法。@RestController注解告诉Spring以字符串的形式渲染结果,并直接返回给调用者。

@EnableAutoConfiguration。这个注解告诉Spring Boot根据添加的jar依赖猜想你想如何配置Spring。因为spring-boot-starter-web添加了Tomcat和Spring MVC,因此auto-configuration将假定你正在开发一个web应用并相应地对Spring进行设置。

main方法。这只是一个标准的方法,它遵循Java对于一个应用程序入口点的约定。咱们的main方法经过调用run,将业务委托给了Spring Boot的SpringApplication类。SpringApplication将引导咱们的应用,启动Spring,相应地启动被自动配置的Tomcat web服务器。咱们须要将Example.class做为参数传递给run方法来告诉SpringApplication谁是主要的Spring组件。

运行:

mvn spring-boot:run 

若是使用一个浏览器打开 localhost:8080,如下输出:

Hello World!

建立可执行jar

为了建立可执行的jar,须要将spring-boot-maven-plugin添加到咱们的pom.xml中。在dependencies节点下插入如下内容:

  1.  
    <build>
  2.  
    <plugins>
  3.  
    <plugin>
  4.  
    <groupId>org.springframework.boot</groupId>
  5.  
    <artifactId>spring-boot-maven-plugin</artifactId>
  6.  
    </plugin>
  7.  
    </plugins>
  8.  
    </build>

注:spring-boot-starter-parent POM包含用于绑定repackage目标的配置。若是你不使用parent POM,你将须要本身声明该配置。具体参考插件文档。

保存你的pom.xml,而后从命令行运行mvn package:

mvn package 

若是查看target目录,你应该看到myproject-0.0.1-SNAPSHOT.jar。该文件应该有10Mb左右的大小。若是想偷看内部结构,你能够运行jar tvf:

jar tvf target/myproject-0.0.1-SNAPSHOT.jar

在target目录下,你应该也能看到一个很小的名为myproject-0.0.1-SNAPSHOT.jar.original的文件。这是在Spring Boot从新打包前Maven建立的原始jar文件。

为了运行该应用程序,你可使用java -jar命令:

java -jar target/myproject-0.0.1-SNAPSHOT.jar

2. 使用Spring Boot

2.1 maven

Maven用户能够继承spring-boot-starter-parent项目来获取合适的默认设置。该父项目提供如下特性:

  1.  
    默认编译级别为 Java 1.6
  2.  
    源码编码为 UTF-8
  3.  
    一个依赖管理节点,容许你省略普通依赖的< version>标签,继承自spring-boot-dependencies POM。
  4.  
    合适的资源过滤
  5.  
    合适的插件配置( exec插件,surefire,Git commit ID,shade)
  6.  
    针对 application.properties和application.xml的资源过滤

最后一点:因为默认配置文件接收Spring风格的占位符(${...}),Maven filtering改用@..@占位符(你可使用Maven属性resource.delimiter来覆盖它)。

想配置你的项目继承spring-boot-starter-parent只须要简单地设置parent为:

  1.  
    <!-- Inherit defaults from Spring Boot -->
  2.  
    <parent>
  3.  
    <groupId>org.springframework.boot</groupId>
  4.  
    <artifactId>spring-boot-starter-parent</artifactId>
  5.  
    <version>1.3.0.BUILD-SNAPSHOT</version>
  6.  
    </parent>

注:你应该只须要在该依赖上指定Spring Boot版本。若是导入其余的starters,你能够放心的省略版本号。

使用没有父POM的Spring Boot

不是每一个人都喜欢继承spring-boot-starter-parent POM。你可能须要使用公司标准parent,或你可能倾向于显式声明全部Maven配置。

若是你不使用spring-boot-starter-parent,经过使用一个scope=import的依赖,你仍能获取到依赖管理的好处:

  1.  
    <dependencyManagement>
  2.  
    <dependencies>
  3.  
    <dependency>
  4.  
    <!-- Import dependency management from Spring Boot -->
  5.  
    <groupId>org.springframework.boot</groupId>
  6.  
    <artifactId>spring-boot-dependencies</artifactId>
  7.  
    <version>1.3.0.BUILD-SNAPSHOT</version>
  8.  
    <type>pom</type>
  9.  
    <scope>import</scope>
  10.  
    </dependency>
  11.  
    </dependencies>
  12.  
    </dependencyManagement>

改变Java版本

spring-boot-starter-parent选择至关保守的Java兼容策略。若是你遵循咱们的建议,使用最新的Java版本,你能够添加一个java.version属性:

  1.  
    <properties>
  2.  
    <java.version>1.8</java.version>
  3.  
    </properties>

** 使用Spring Boot Maven插件**

Spring Boot包含一个Maven插件,它能够将项目打包成一个可执行jar。若是想使用它,你能够将该插件添加到节点处:

  1.  
    <build>
  2.  
    <plugins>
  3.  
    <plugin>
  4.  
    <groupId>org.springframework.boot</groupId>
  5.  
    <artifactId>spring-boot-maven-plugin</artifactId>
  6.  
    </plugin>
  7.  
    </plugins>
  8.  
    </build>

注:若是使用Spring Boot starter parent pom,你只须要添加该插件而无需配置它,除非你想改变定义在partent中的设置。

2.2 组织代码

Spring Boot不须要使用任何特殊的代码结构,然而,这里有一些有用的最佳实践。

使用"default"包

当类没有包含package声明时,它被认为处于default package下。一般不推荐使用default package,并应该避免使用它。由于对于使用@ComponentScan,@EntityScan或@SpringBootApplication注解的Spring Boot应用来讲,来自每一个jar的类都会被读取,这会形成必定的问题。

定位main应用类

咱们一般建议你将main应用类放在位于其余类上面的根包(root package)中。一般使用@EnableAutoConfiguration注解你的main类,而且暗地里为某些项定义了一个基础“search package”。例如,若是你正在编写一个JPA应用,被@EnableAutoConfiguration注解的类所在包将被用来搜索@Entity项。

使用根包容许你使用@ComponentScan注解而不须要定义一个basePackage属性。若是main类位于根包中,你也可使用@SpringBootApplication注解。

下面是一个典型的结构:

  1.  
    com
  2.  
    +- example
  3.  
    +- myproject
  4.  
    +- Application.java
  5.  
    |
  6.  
    +- domain
  7.  
    | +- Customer.java
  8.  
    | +- CustomerRepository.java
  9.  
    |
  10.  
    +- service
  11.  
    | +- CustomerService.java
  12.  
    |
  13.  
    +- web
  14.  
    +- CustomerController.java

Application.java文件将声明main方法,还有基本的@Configuration。

  1.  
    package com.example.myproject;
  2.  
     
  3.  
    import org.springframework.boot.SpringApplication;
  4.  
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  5.  
    import org.springframework.context.annotation.ComponentScan;
  6.  
    import org.springframework.context.annotation.Configuration;
  7.  
     
  8.  
    @Configuration
  9.  
    @EnableAutoConfiguration
  10.  
    @ComponentScan
  11.  
    public class Application {
  12.  
     
  13.  
    public static void main(String[] args) {
  14.  
    SpringApplication.run(Application.class, args);
  15.  
    }
  16.  
     
  17.  
    }

2.3 配置类

Spring Boot提倡基于Java的配置。尽管你可使用一个XML源来调用SpringApplication.run(),咱们一般建议你使用@Configuration类做为主要源。通常定义main方法的类也是主要@Configuration的一个很好候选。

一、导入其余配置类

你不须要将全部的@Configuration放进一个单独的类。@Import注解能够用来导入其余配置类。另外,你也可使用@ComponentScan注解自动收集全部的Spring组件,包括@Configuration类。

二、导入XML配置

若是你绝对须要使用基于XML的配置,咱们建议你仍旧从一个@Configuration类开始。你可使用附加的@ImportResource注解加载XML配置文件。

2.4 自动配置

Spring Boot自动配置(auto-configuration)尝试根据你添加的jar依赖自动配置你的Spring应用。例如,若是你的classpath下存在HSQLDB,而且你没有手动配置任何数据库链接beans,那么咱们将自动配置一个内存型(in-memory)数据库。

你能够经过将@EnableAutoConfiguration或@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。

注:你只须要添加一个@EnableAutoConfiguration注解。咱们建议你将它添加到主@Configuration类上。

禁用特定的自动配置

若是发现应用了你不想要的特定自动配置类,你可使用@EnableAutoConfiguration注解的排除属性来禁用它们。

  1.  
    import org.springframework.boot.autoconfigure.*;
  2.  
    import org.springframework.boot.autoconfigure.jdbc.*;
  3.  
    import org.springframework.context.annotation.*;
  4.  
     
  5.  
    @ Configuration
  6.  
    @EnableAutoConfiguration(exclude={ DataSourceAutoConfiguration.class})
  7.  
    public class MyConfiguration {
  8.  
    }

2.5 Spring Beans和依赖注入

你能够自由地使用任何标准的Spring框架技术去定义beans和它们注入的依赖。简单起见,咱们常用@ComponentScan注解搜索beans,并结合@Autowired构造器注入。

若是使用上面建议的结构组织代码(将应用类放到根包下),你能够添加@ComponentScan注解而不须要任何参数。你的全部应用程序组件(@Component, @Service, @Repository, @Controller等)将被自动注册为Spring Beans。

下面是一个@Service Bean的示例,它使用构建器注入获取一个须要的RiskAssessor bean。

  1.  
    package com.example.service;
  2.  
     
  3.  
    import org.springframework.beans.factory.annotation.Autowired;
  4.  
    import org.springframework.stereotype.Service;
  5.  
     
  6.  
    @Service
  7.  
    public class DatabaseAccountService implements AccountService {
  8.  
     
  9.  
    private final RiskAssessor riskAssessor;
  10.  
     
  11.  
    @Autowired
  12.  
    public DatabaseAccountService(RiskAssessor riskAssessor) {
  13.  
    this.riskAssessor = riskAssessor;
  14.  
    }
  15.  
     
  16.  
    // ...
  17.  
    }

注:注意如何使用构建器注入来容许riskAssessor字段被标记为final,这意味着riskAssessor后续是不能改变的。

2.6 使用@SpringBootApplication注解

不少Spring Boot开发者老是使用@Configuration,@EnableAutoConfiguration和@ComponentScan注解他们的main类。因为这些注解被如此频繁地一块使用(特别是你遵循以上最佳实践时),Spring Boot提供一个方便的@SpringBootApplication选择。

该@SpringBootApplication注解等价于以默认属性使用@Configuration,@EnableAutoConfiguration和@ComponentScan。

  1.  
    package com.example.myproject;
  2.  
    import org.springframework.boot.SpringApplication;
  3.  
    import org.springframework.boot.autoconfigure.SpringBootApplication;
  4.  
     
  5.  
    @SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
  6.  
    public class Application {
  7.  
     
  8.  
    public static void main(String[] args) {
  9.  
    SpringApplication.run(Application.class, args);
  10.  
    }
  11.  
     
  12.  
    }

2.7 做为一个打包后的应用运行

若是使用Spring Boot Maven或Gradle插件建立一个可执行jar,你可使用java -jar运行你的应用。例如:

java -jar target/myproject-0.0.1-SNAPSHOT.jar

运行一个打包的程序并开启远程调试支持是可能的,这容许你将调试器附加到打包的应用程序上:

  1.  
    java -Xdebug -Xrunjdwp: server=y,transport=dt_socket,address=8000,suspend=n \
  2.  
    -jar target/myproject -0.0.1-SNAPSHOT.jar

2.8 使用Maven插件运行

Spring Boot Maven插件包含一个run目标,它能够用来快速编译和运行应用程序。应用程序以一种暴露的方式运行,因为即时"热"加载,你能够编辑资源。

mvn spring-boot:run 

你可能想使用有用的操做系统环境变量:

export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M -Djava.security.egd=file:/dev/./urandom 

3 Spring Boot特性

3.1 SpringApplication

SpringApplication类提供了一种从main()方法启动Spring应用的便捷方式。在不少状况下,你只需委托给SpringApplication.run这个静态方法:

  1.  
    public static void main(String[] args){
  2.  
    SpringApplication.run(MySpringConfiguration.class, args);
  3.  
    }

当应用启动时,你应该会看到相似下面的东西(这是何方神兽??):

  1.  
    . ___ _ _ __ _ _
  2.  
    /\\ / __ _'_ __ _ _(_)_ __ __ _ \ \ \ \
  3.  
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
  4.  
    \\/ __ _)| |_)| | | | | || (_| | ) ) ) )
  5.  
    ' |____| .__|_| |_|_| |_\__, | / / / /
  6.  
    ========= |_|==============|___/=/_/_/_/
  7.  
    :: Spring Boot :: v1.2.2.BUILD-SNAPSHOT
  8.  
     
  9.  
    2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
  10.  
    2013-07-31 00:08:16.166 INFO 56603 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
  11.  
    2014-03-04 13:09:54.912 INFO 41370 --- [ main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
  12.  
    2014-03-04 13:09:56.501 INFO 41370 --- [ main] o.s.b.s.app.SampleApplication : S
  13.  
     

默认状况下会显示INFO级别的日志信息,包括一些相关的启动详情,好比启动应用的用户等。

3.1.1 自定义Banner

经过在classpath下添加一个banner.txt或设置banner.location来指定相应的文件能够改变启动过程当中打印的banner。若是这个文件有特殊的编码,你可使用banner.encoding设置它(默认为UTF-8)。

在banner.txt中可使用以下的变量:

  1.  
    变量 描述
  2.  
    ${application.version} MANIFEST.MF中声明的应用版本号,例如1.0
  3.  
    ${application.formatted-version} MANIFEST.MF中声明的被格式化后的应用版本号(被括号包裹且以v做为前缀),用于显示,例如(v1.0)
  4.  
    ${spring-boot.version} 正在使用的Spring Boot版本号,例如1.2.2.BUILD-SNAPSHOT
  5.  
    ${spring-boot.formatted-version} 正在使用的Spring Boot被格式化后的版本号(被括号包裹且以v做为前缀), 用于显示,例如(v1.2.2.BUILD-SNAPSHOT)

注:若是想以编程的方式产生一个banner,可使用SpringBootApplication.setBanner(…)方法。使用org.springframework.boot.Banner接口,实现你本身的printBanner()方法。

3.1.2 自定义SpringApplication

若是默认的SpringApplication不符合你的口味,你能够建立一个本地的实例并自定义它。例如,关闭banner你能够这样写:

  1.  
    public static void main(String[] args){
  2.  
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
  3.  
    app.setShowBanner( false);
  4.  
    app.run(args);
  5.  
    }

注:传递给SpringApplication的构造器参数是spring beans的配置源。在大多数状况下,这些将是@Configuration类的引用,但它们也多是XML配置或要扫描包的引用。

3.1.3 流畅的构建API

若是你须要建立一个分层的ApplicationContext(多个具备父子关系的上下文),或你只是喜欢使用流畅的构建API,你可使用SpringApplicationBuilder。SpringApplicationBuilder容许你以链式方式调用多个方法,包括能够建立层次结构的parent和child方法。

  1.  
    new SpringApplicationBuilder()
  2.  
    .showBanner(false)
  3.  
    .sources(Parent.class)
  4.  
    .child(Application.class)
  5.  
    .run(args);

注:建立ApplicationContext层次时有些限制,好比,Web组件(components)必须包含在子上下文(child context)中,且相同的Environment即用于父上下文也用于子上下文中。

3.1.4 Application事件和监听器

除了常见的Spring框架事件,好比ContextRefreshedEvent,一个SpringApplication也发送一些额外的应用事件。一些事件其实是在ApplicationContext被建立前触发的。

你可使用多种方式注册事件监听器,最普通的是使用SpringApplication.addListeners(…)方法。在你的应用运行时,应用事件会如下面的次序发送:

  1.  
    在运行开始,但除了监听器注册和初始化之外的任何处理以前,会发送一个ApplicationStartedEvent。
  2.  
     
  3.  
    在Environment将被用于已知的上下文,但在上下文被建立前,会发送一个ApplicationEnvironmentPreparedEvent。
  4.  
     
  5.  
    在refresh开始前,但在bean定义已被加载后,会发送一个ApplicationPreparedEvent。
  6.  
     
  7.  
    启动过程当中若是出现异常,会发送一个ApplicationFailedEvent。

注:你一般不须要使用应用程序事件,但知道它们的存在会很方便(在某些场合可能会使用到)。在Spring内部,Spring Boot使用事件处理各类各样的任务。

3.1.5 Web环境

一个SpringApplication将尝试为你建立正确类型的ApplicationContext。在默认状况下,使用AnnotationConfigApplicationContext或AnnotationConfigEmbeddedWebApplicationContext取决于你正在开发的是不是web应用。

用于肯定一个web环境的算法至关简单(基因而否存在某些类)。若是须要覆盖默认行为,你可使用setWebEnvironment(boolean webEnvironment)。经过调用setApplicationContextClass(…),你能够彻底控制ApplicationContext的类型。

注:当JUnit测试里使用SpringApplication时,调用setWebEnvironment(false)是可取的。

3.1.6 命令行启动器

若是你想获取原始的命令行参数,或一旦SpringApplication启动,你须要运行一些特定的代码,你能够实现CommandLineRunner接口。在全部实现该接口的Spring beans上将调用run(String… args)方法。

  1.  
    import org.springframework.boot.*
  2.  
    import org.springframework.stereotype.*
  3.  
     
  4.  
    @Component
  5.  
    public class MyBean implements CommandLineRunner {
  6.  
    public void run(String... args) {
  7.  
    // Do something...
  8.  
    }
  9.  
    }

若是一些CommandLineRunner beans被定义必须以特定的次序调用,你能够额外实现org.springframework.core.Ordered接口或使用org.springframework.core.annotation.Order注解。

3.1.7 Application退出

每一个SpringApplication在退出时为了确保ApplicationContext被优雅的关闭,将会注册一个JVM的shutdown钩子。全部标准的Spring生命周期回调(好比,DisposableBean接口或@PreDestroy注解)都能使用。

此外,若是beans想在应用结束时返回一个特定的退出码(exit code),能够实现org.springframework.boot.ExitCodeGenerator接口。

4 外化配置

Spring Boot容许外化(externalize)你的配置,这样你可以在不一样的环境下使用相同的代码。你可使用properties文件,YAML文件,环境变量和命令行参数来外化配置。使用@Value注解,能够直接将属性值注入到你的beans中,并经过Spring的Environment抽象或绑定到结构化对象来访问。

Spring Boot使用一个很是特别的PropertySource次序来容许对值进行合理的覆盖,须要如下面的次序考虑属性:

  1.  
    命令行参数
  2.  
    来自于java:comp/env的JNDI属性
  3.  
    Java系统属性(System.getProperties())
  4.  
    操做系统环境变量
  5.  
    只有在random.*里包含的属性会产生一个RandomValuePropertySource
  6.  
    在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)
  7.  
    在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)
  8.  
    @Configuration类上的@PropertySource注解
  9.  
    默认属性(使用SpringApplication.setDefaultProperties指定)

下面是一个具体的示例(假设你开发一个使用name属性的@Component):

  1.  
    import org.springframework.stereotype.*
  2.  
    import org.springframework.beans.factory.annotation.*
  3.  
     
  4.  
    @Component
  5.  
    public class MyBean {
  6.  
    @Value("${name}")
  7.  
    private String name;
  8.  
    // ...
  9.  
    }

你能够将一个application.properties文件捆绑到jar内,用来提供一个合理的默认name属性值。当运行在生产环境时,能够在jar外提供一个application.properties文件来覆盖name属性。对于一次性的测试,你可使用特定的命令行开关启动(好比,java -jar app.jar --name="Spring")。

4.1 配置随机值

RandomValuePropertySource在注入随机值(好比,密钥或测试用例)时颇有用。它能产生整数,longs或字符串,好比:

  1.  
    my.secret=${random. value}
  2.  
    my.number=${random. int}
  3.  
    my.bignumber=${random. long}
  4.  
    my.number.less.than.ten=${random. int(10)}
  5.  
    my.number. in.range=${random.int[1024,65536]}

random.int*语法是OPEN value (,max) CLOSE,此处OPEN,CLOSE能够是任何字符,而且value,max是整数。若是提供max,那么value是最小的值,max是最大的值(不包含在内)。

4.2访问命令行属性

默认状况下,SpringApplication将任何可选的命令行参数(以'--'开头,好比,--server.port=9000)转化为property,并将其添加到Spring Environment中。如上所述,命令行属性老是优先于其余属性源。

若是你不想将命令行属性添加到Environment里,你可使用SpringApplication.setAddCommandLineProperties(false)来禁止它们。

4.3 Application属性文件

SpringApplication将从如下位置加载application.properties文件,并把它们添加到Spring Environment中:

  1.  
    当前目录下的一个/config子目录
  2.  
    当前目录
  3.  
    一个classpath下的/config包
  4.  
    classpath根路径(root)

这个列表是按优先级排序的(列表中位置高的将覆盖位置低的)。

注:你可使用YAML('.yml')文件替代'.properties'。

若是不喜欢将application.properties做为配置文件名,你能够经过指定spring.config.name环境属性来切换其余的名称。你也可使用spring.config.location环境属性来引用一个明确的路径(目录位置或文件路径列表以逗号分割)。

  1.  
    $ java -jar myproject.jar --spring.config. name=myproject
  2.  
    //or
  3.  
    $ java -jar myproject.jar --spring.config.location=classpath:/ default.properties,classpath:/override.properties

若是spring.config.location包含目录(相对于文件),那它们应该以/结尾(在加载前,spring.config.name产生的名称将被追加到后面)。无论spring.config.location是什么值,默认的搜索路径classpath:,classpath:/config,file:,file:config/总会被使用。以这种方式,你能够在application.properties中为应用设置默认值,而后在运行的时候使用不一样的文件覆盖它,同时保留默认配置。

注:若是你使用环境变量而不是系统配置,大多数操做系统不容许以句号分割(period-separated)的key名称,但你可使用下划线(underscores)代替(好比,使用SPRINGCONFIGNAME代替spring.config.name)。若是你的应用运行在一个容器中,那么JNDI属性(java:comp/env)或servlet上下文初始化参数能够用来取代环境变量或系统属性,固然也可使用环境变量或系统属性。

4.4 特定的Profile属性

除了application.properties文件,特定配置属性也能经过命令惯例application-{profile}.properties来定义。特定Profile属性从跟标准application.properties相同的路径加载,而且特定profile文件会覆盖默认的配置。

4.5 属性占位符

当application.properties里的值被使用时,它们会被存在的Environment过滤,因此你可以引用先前定义的值(好比,系统属性)。

  1.  
    app. name=MyApp
  2.  
    app.description=$ {app.name} is a Spring Boot application

4.6 使用YAML代替Properties

YAML是JSON的一个超集,也是一种方便的定义层次配置数据的格式。不管你什么时候将SnakeYAML 库放到classpath下,SpringApplication类都会自动支持YAML做为properties的替换。

注:若是你使用'starter POMs',spring-boot-starter会自动提供SnakeYAML。

4.6.1. 加载YAML

Spring框架提供两个便利的类用于加载YAML文档,YamlPropertiesFactoryBean会将YAML做为Properties来加载,YamlMapFactoryBean会将YAML做为Map来加载。

示例:

  1.  
    environments:
  2.  
    dev:
  3.  
    url: http: //dev.bar.com
  4.  
    name: Developer Setup
  5.  
    prod:
  6.  
    url: http: //foo.bar.com
  7.  
    name: My Cool App

上面的YAML文档会被转化到下面的属性中:

  1.  
    environments.dev.url=http: //dev.bar.com
  2.  
    environments.dev. name=Developer Setup
  3.  
    environments.prod.url=http: //foo.bar.com
  4.  
    environments.prod. name=My Cool App

YAML列表被表示成使用[index]间接引用做为属性keys的形式,例以下面的YAML:

  1.  
    my:
  2.  
    servers:
  3.  
    - dev.bar.com
  4.  
    - foo.bar.com

将会转化到下面的属性中:

  1.  
    my.servers[0]=dev.bar.com
  2.  
    my.servers[1]=foo.bar.com

使用Spring DataBinder工具绑定那样的属性(这是@ConfigurationProperties作的事),你须要肯定目标bean中有个java.util.List或Set类型的属性,而且须要提供一个setter或使用可变的值初始化它,好比,下面的代码将绑定上面的属性:

  1.  
    @ConfigurationProperties(prefix="my")
  2.  
    public class Config {
  3.  
    private List<String> servers = new ArrayList<String>();
  4.  
    public List<String> getServers() {
  5.  
    return this.servers;
  6.  
    }
  7.  
    }

4.6.2. 在Spring环境中使用YAML暴露属性

YamlPropertySourceLoader类可以用于将YAML做为一个PropertySource导出到Sprig Environment。这容许你使用熟悉的@Value注解和占位符语法访问YAML属性。

4.6.3. Multi-profile YAML文档

你能够在单个文件中定义多个特定配置(profile-specific)的YAML文档,并经过一个spring.profiles key标示应用的文档。例如:

  1.  
    server:
  2.  
    address: 192.168.1.100
  3.  
    ---
  4.  
    spring:
  5.  
    profiles: development
  6.  
    server:
  7.  
    address: 127.0.0.1
  8.  
    ---
  9.  
    spring:
  10.  
    profiles: production
  11.  
    server:
  12.  
    address: 192.168.1.120

在上面的例子中,若是development配置被激活,那server.address属性将是127.0.0.1。若是development和production配置(profiles)没有启用,则该属性的值将是192.168.1.100。

YAML缺点

YAML文件不能经过@PropertySource注解加载。因此,在这种状况下,若是须要使用@PropertySource注解的方式加载值,那就要使用properties文件。

4.7. 类型安全的配置属性

使用@Value("${property}")注解注入配置属性有时可能比较笨重,特别是须要使用多个properties或你的数据自己有层次结构。为了控制和校验你的应用配置,Spring Boot提供一个容许强类型beans的替代方法来使用properties。

示例:

  1.  
    @Component
  2.  
    @ConfigurationProperties(prefix="connection")
  3.  
    public class ConnectionSettings {
  4.  
    private String username;
  5.  
    private InetAddress remoteAddress;
  6.  
    // ... getters and setters
  7.  
    }

当@EnableConfigurationProperties注解应用到你的@Configuration时,任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。

  1.  
    # application.yml
  2.  
    connection:
  3.  
    username: admin
  4.  
    remoteAddress: 192.168.1.1
  5.  
    # additional configuration as required

为了使用@ConfigurationProperties beans,你可使用与其余任何bean相同的方式注入它们。

  1.  
    @Service
  2.  
    public class MyService {
  3.  
    @Autowired
  4.  
    private ConnectionSettings connection;
  5.  
    //...
  6.  
    @PostConstruct
  7.  
    public void openConnection() {
  8.  
    Server server = new Server();
  9.  
    this.connection.configure(server);
  10.  
    }
  11.  
    }

你能够经过在@EnableConfigurationProperties注解中直接简单的列出属性类来快捷的注册@ConfigurationProperties bean的定义。

  1.  
    @Configuration
  2.  
    @EnableConfigurationProperties(ConnectionSettings.class)
  3.  
    public class MyConfiguration {
  4.  
    }

注:使用@ConfigurationProperties可以产生可被IDEs使用的元数据文件。具体参考Appendix B, Configuration meta-data。

4.7.1. 第三方配置

正如使用@ConfigurationProperties注解一个类,你也能够在@Bean方法上使用它。当你须要绑定属性到不受你控制的第三方组件时,这种方式很是有用。

为了从Environment属性配置一个bean,将@ConfigurationProperties添加到它的bean注册过程:

  1.  
    @ConfigurationProperties(prefix = "foo")
  2.  
    @Bean
  3.  
    public FooComponent fooComponent() {
  4.  
    ...
  5.  
    }

和上面ConnectionSettings的示例方式相同,任何以foo为前缀的属性定义都会被映射到FooComponent上。

4.7.2. 松散的绑定(Relaxed binding)

Spring Boot使用一些宽松的规则用于绑定Environment属性到@ConfigurationProperties beans,因此Environment属性名和bean属性名不须要精确匹配。常见的示例中有用的包括虚线分割(好比,context--path绑定到contextPath)和将环境属性转为大写字母(好比,PORT绑定port)。

示例:

  1.  
    @Component
  2.  
    @ConfigurationProperties(prefix="person")
  3.  
    public class ConnectionSettings {
  4.  
    private String firstName;
  5.  
    }

下面的属性名都能用于上面的@ConfigurationProperties类:

  1.  
    属性 说明
  2.  
    person.firstName 标准驼峰规则
  3.  
    person.first-name 虚线表示,推荐用于.properties和.yml文件中
  4.  
    PERSON_FIRST_NAME 大写形式,使用系统环境变量时推荐

Spring会尝试强制外部的应用属性在绑定到@ConfigurationProperties beans时类型是正确的。若是须要自定义类型转换,你能够提供一个ConversionService bean(bean id为conversionService)或自定义属性编辑器(经过一个CustomEditorConfigurer bean)。

4.7.3. @ConfigurationProperties校验

Spring Boot将尝试校验外部的配置,默认使用JSR-303(若是在classpath路径中)。你能够轻松的为你的@ConfigurationProperties类添加JSR-303 javax.validation约束注解:

  1.  
    @Component
  2.  
    @ConfigurationProperties(prefix="connection")
  3.  
    public class ConnectionSettings {
  4.  
    @NotNull
  5.  
    private InetAddress remoteAddress;
  6.  
    // ... getters and setters
  7.  
    }

你也能够经过建立一个叫作configurationPropertiesValidator的bean来添加自定义的Spring Validator。

注:spring-boot-actuator模块包含一个暴露全部@ConfigurationProperties beans的端点。

5 Profiles

Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只能在特定的环境下生效。任何@Component或@Configuration都能被@Profile标记,从而限制加载它的时机。

  1.  
    @Configuration
  2.  
    @Profile("production")
  3.  
    public class ProductionConfiguration {
  4.  
    // ...
  5.  
    }

以正常的Spring方式,你可使用一个spring.profiles.active的Environment属性来指定哪一个配置生效。你可使用日常的任何方式来指定该属性,例如,能够将它包含到你的application.properties中:

  1.  
    spring.profiles.active=dev,hsqldb
  2.  
    或使用命令行开关:
  3.  
     
  4.  
    --spring.profiles.active=dev,hsqldb

5.1. 添加激活的配置(profiles)

spring.profiles.active属性和其余属性同样都遵循相同的排列规则,最高的PropertySource获胜。也就是说,你能够在application.properties中指定生效的配置,而后使用命令行开关替换它们。

有时,将特定的配置属性添加到生效的配置中而不是替换它们是有用的。spring.profiles.include属性能够用来无条件的添加生效的配置。SpringApplication的入口点也提供了一个用于设置额外配置的Java API(好比,在那些经过spring.profiles.active属性生效的配置之上):参考setAdditionalProfiles()方法。

示例:当一个应用使用下面的属性,并用--spring.profiles.active=prod开关运行,那proddb和prodmq配置也会生效:

  1.  
    ---
  2.  
    my.property: fromyamlfile
  3.  
    ---
  4.  
    spring.profiles: prod
  5.  
    spring.profiles.include: proddb,prodmq

注:spring.profiles属性能够定义到一个YAML文档中,用于决定何时该文档被包含进配置中。

5.2.以编程方式设置profiles

在应用运行前,你能够经过调用SpringApplication.setAdditionalProfiles(…)方法,以编程的方式设置生效的配置。使用Spring的ConfigurableEnvironment接口激动配置也是可行的。

5.3. Profile特定配置文件

application.properties(或application.yml)和经过@ConfigurationProperties引用的文件这两种配置特定变种都被看成文件来加载的,具体参考Section 23.3, “Profile specific properties”。

6 日志

Spring Boot内部日志系统使用的是Commons Logging,但开放底层的日志实现。默认为会Java Util Logging, Log4J, Log4J2和Logback提供配置。每种状况下都会预先配置使用控制台输出,也可使用可选的文件输出。

默认状况下,若是你使用'Starter POMs',那么就会使用Logback记录日志。为了确保那些使用Java Util Logging, Commons Logging, Log4J或SLF4J的依赖库可以正常工做,正确的Logback路由也被包含进来。

注:若是上面的列表看起来使人困惑,不要担忧,Java有不少可用的日志框架。一般,你不须要改变日志依赖,Spring Boot默认的就能很好的工做。

6.1. 日志格式

Spring Boot默认的日志输出格式以下:

  1.  
    2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52
  2.  
    2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
  3.  
    2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
  4.  
    2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
  5.  
    2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  6.  
     

输出的节点(items)以下:

  1.  
    日期和时间 - 精确到毫秒,且易于排序。
  2.  
    日志级别 - ERROR, WARN, INFO, DEBUG 或 TRACE。
  3.  
    Process ID。
  4.  
    一个用于区分实际日志信息开头的---分隔符。
  5.  
    线程名 - 包括在方括号中(控制台输出可能会被截断)。
  6.  
    日志名 - 一般是源 class的类名(缩写)。
  7.  
    日志信息。

5.2. 控制台输出

默认的日志配置会在写日志消息时将它们回显到控制台。默认,ERROR, WARN和INFO级别的消息会被记录。能够在启动应用时,经过--debug标识开启控制台的DEBUG级别日志记录。

java -jar myapp.jar --debug 

若是你的终端支持ANSI,为了增长可读性将会使用彩色的日志输出。你能够设置spring.output.ansi.enabled为一个支持的值来覆盖自动检测。

5.3. 文件输出

默认状况下,Spring Boot只会将日志记录到控制台而不会写进日志文件。若是除了输出到控制台你还想写入到日志文件,那你须要设置logging.file或logging.path属性(例如在你的application.properties中)。

下表显示如何组合使用logging.*:

  1.  
    logging.file logging.path 示例 描述
  2.  
    ( none) (none) 只记录到控制台
  3.  
    Specific file (none) my.log 写到特定的日志文件里,名称能够是一个精确的位置或相对于当前目录
  4.  
    ( none) Specific folder /var/log 写到特定文件夹下的spring.log里,名称能够是一个精确的位置或相对于当前目录

日志文件每达到10M就会被轮换(分割),和控制台同样,默认记录ERROR, WARN和INFO级别的信息。

5.4. 日志级别

全部支持的日志系统在Spring的Environment(例如在application.properties里)都有经过'logging.level.*=LEVEL'('LEVEL'是TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF中的一个)设置的日志级别。

示例:application.properties

  1.  
    logging.level.org.springframework.web: DEBUG
  2.  
    logging.level.org.hibernate: ERROR

5.5. 自定义日志配置

经过将适当的库添加到classpath,能够激活各类日志系统。而后在classpath的根目录(root)或经过Spring Environment的logging.config属性指定的位置提供一个合适的配置文件来达到进一步的定制(注意因为日志是在ApplicationContext被建立以前初始化的,因此不可能在Spring的@Configuration文件中,经过@PropertySources控制日志。系统属性和日常的Spring Boot外部配置文件能正常工做)。

根据你的日志系统,下面的文件会被加载:

  1.  
    日志系统 定制
  2.  
    Logback logback.xml
  3.  
    Log4j log4j.properties或log4j.xml
  4.  
    Log4j2 log4j2.xml
  5.  
    JDK (Java Util Logging) logging.properties

为了帮助定制一些其余的属性,从Spring的Envrionment转换到系统属性:

  1.  
    Spring Environment System Property 评价
  2.  
    logging.file LOG_FILE 若是定义,在默认的日志配置中使用
  3.  
    logging.path LOG_PATH 若是定义,在默认的日志配置中使用
  4.  
    PID PID 当前的处理进程(process)ID(若是可以被发现且尚未做为操做系统环境变量被定义)

全部支持的日志系统在解析它们的配置文件时都能查询系统属性。具体能够参考spring-boot.jar中的默认配置。

注:在运行可执行的jar时,Java Util Logging有类加载问题,咱们建议你尽量避免使用它。

6 开发Web应用

Spring Boot很是适合开发web应用程序。你可使用内嵌的Tomcat,Jetty或Undertow轻轻松松地建立一个HTTP服务器。大多数的web应用都使用spring-boot-starter-web模块进行快速搭建和运行。

6.1. Spring Web MVC框架

Spring Web MVC框架(一般简称为"Spring MVC")是一个富"模型,视图,控制器"的web框架。 Spring MVC容许你建立特定的@Controller或@RestController beans来处理传入的HTTP请求。 使用@RequestMapping注解能够将控制器中的方法映射到相应的HTTP请求。

示例:

  1.  
    @RestController
  2.  
    @RequestMapping(value="/users")
  3.  
    public class MyRestController {
  4.  
     
  5.  
    @RequestMapping(value="/{user}", method=RequestMethod.GET)
  6.  
    public User getUser(@PathVariable Long user) {
  7.  
    // ...
  8.  
    }
  9.  
     
  10.  
    @RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
  11.  
    List<Customer> getUserCustomers( @PathVariable Long user) {
  12.  
    // ...
  13.  
    }
  14.  
     
  15.  
    @RequestMapping(value="/{user}", method=RequestMethod.DELETE)
  16.  
    public User deleteUser(@PathVariable Long user) {
  17.  
    // ...
  18.  
    }
  19.  
    }

6.1.1. Spring MVC自动配置

Spring Boot为Spring MVC提供适用于多数应用的自动配置功能。在Spring默认基础上,自动配置添加了如下特性:

  1.  
    引入 ContentNegotiatingViewResolver和BeanNameViewResolver beans。
  2.  
    对静态资源的支持,包括对 WebJars的支持。
  3.  
    自动注册 Converter,GenericConverter,Formatter beans。
  4.  
    HttpMessageConverters的支持。
  5.  
    自动注册 MessageCodeResolver。
  6.  
    对静态 index.html的支持。
  7.  
    对自定义 Favicon的支持。

若是想全面控制Spring MVC,你能够添加本身的@Configuration,并使用@EnableWebMvc对其注解。若是想保留Spring Boot MVC的特性,并只是添加其余的MVC配置(拦截器,formatters,视图控制器等),你能够添加本身的WebMvcConfigurerAdapter类型的@Bean(不使用@EnableWebMvc注解)。

6.1.2. HttpMessageConverters

Spring MVC使用HttpMessageConverter接口转换HTTP请求和响应。合理的缺省值被包含的恰到好处(out of the box),例如对象能够自动转换为JSON(使用Jackson库)或XML(若是Jackson XML扩展可用则使用它,不然使用JAXB)。字符串默认使用UTF-8编码。

若是须要添加或自定义转换器,你可使用Spring Boot的HttpMessageConverters类:

  1.  
    import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
  2.  
    import org.springframework.context.annotation.*;
  3.  
    import org.springframework.http.converter.*;
  4.  
     
  5.  
    @Configuration
  6.  
    public class MyConfiguration {
  7.  
     
  8.  
    @Bean
  9.  
    public HttpMessageConverters customConverters() {
  10.  
    HttpMessageConverter<?> additional = ...
  11.  
    HttpMessageConverter<?> another = ...
  12.  
    return new HttpMessageConverters(additional, another);
  13.  
    }
  14.  
    }

任何在上下文中出现的HttpMessageConverter bean将会添加到converters列表,你能够经过这种方式覆盖默认的转换器(converters)。

6.1.3. MessageCodesResolver

Spring MVC有一个策略,用于从绑定的errors产生用来渲染错误信息的错误码:MessageCodesResolver。若是设置spring.mvc.message-codes-resolver.format属性为PREFIXERRORCODE或POSTFIXERRORCODE(具体查看DefaultMessageCodesResolver.Format枚举值),Spring Boot会为你建立一个MessageCodesResolver。

6.1.4. 静态内容

默认状况下,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,多数构建工具都会静悄悄的忽略它。

6.1.5. 模板引擎

正如REST web服务,你也可使用Spring MVC提供动态HTML内容。Spring MVC支持各类各样的模板技术,包括Velocity, FreeMarker和JSPs。不少其余的模板引擎也提供它们本身的Spring MVC集成。

Spring Boot为如下的模板引擎提供自动配置支持:

  1.  
    FreeMarker
  2.  
    Groovy
  3.  
    Thymeleaf
  4.  
    Velocity

注:若是可能的话,应该忽略JSPs,由于在内嵌的servlet容器使用它们时存在一些已知的限制。

当你使用这些引擎的任何一种,并采用默认的配置,你的模板将会从src/main/resources/templates目录下自动加载。

注:IntelliJ IDEA根据你运行应用的方式会对classpath进行不一样的整理。在IDE里经过main方法运行你的应用跟从Maven或Gradle或打包好的jar中运行相比会致使不一样的顺序。这可能致使Spring Boot不能从classpath下成功地找到模板。若是遇到这个问题,你能够在IDE里从新对classpath进行排序,将模块的类和资源放到第一位。或者,你能够配置模块的前缀为classpath*:/templates/,这样会查找classpath下的全部模板目录。

6.1.6. 错误处理

Spring Boot默认提供一个/error映射用来以合适的方式处理全部的错误,而且它在servlet容器中注册了一个全局的 错误页面。对于机器客户端(相对于浏览器而言,浏览器偏重于人的行为),它会产生一个具备详细错误,HTTP状态,异常信息的JSON响应。对于浏览器客户端,它会产生一个白色标签样式(whitelabel)的错误视图,该视图将以HTML格式显示一样的数据(能够添加一个解析为erro的View来自定义它)。为了彻底替换默认的行为,你能够实现ErrorController,并注册一个该类型的bean定义,或简单地添加一个ErrorAttributes类型的bean以使用现存的机制,只是替换显示的内容。

若是在某些条件下须要比较多的错误页面,内嵌的servlet容器提供了一个统一的Java DSL(领域特定语言)来自定义错误处理。 示例:

  1.  
    @Bean
  2.  
    public EmbeddedServletContainerCustomizer containerCustomizer(){
  3.  
    return new MyCustomizer();
  4.  
    }
  5.  
     
  6.  
    // ...
  7.  
    private static class MyCustomizer implements EmbeddedServletContainerCustomizer {
  8.  
    @Override
  9.  
    public void customize(ConfigurableEmbeddedServletContainer container) {
  10.  
    container.addErrorPages( new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
  11.  
    }
  12.  
    }

你也可使用常规的Spring MVC特性来处理错误,好比@ExceptionHandler方法和@ControllerAdvice。ErrorController将会捡起任何没有处理的异常。

N.B. 若是你为一个路径注册一个ErrorPage,最终被一个过滤器(Filter)处理(对于一些非Spring web框架,像Jersey和Wicket这很常见),而后过滤器须要显式注册为一个ERROR分发器(dispatcher)。

  1.  
    @Bean
  2.  
    public FilterRegistrationBean myFilter() {
  3.  
    FilterRegistrationBean registration = new FilterRegistrationBean();
  4.  
    registration.setFilter( new MyFilter());
  5.  
    ...
  6.  
    registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
  7.  
    return registration;
  8.  
    }

注:默认的FilterRegistrationBean没有包含ERROR分发器类型。

6.1.7. Spring HATEOAS

若是你正在开发一个使用超媒体的RESTful API,Spring Boot将为Spring HATEOAS提供自动配置,这在多数应用中都工做良好。自动配置替换了对使用@EnableHypermediaSupport的需求,并注册必定数量的beans来简化构建基于超媒体的应用,这些beans包括一个LinkDiscoverer和配置好的用于将响应正确编排为想要的表示的ObjectMapper。ObjectMapper能够根据spring.jackson.*属性或一个存在的Jackson2ObjectMapperBuilder bean进行自定义。

经过使用@EnableHypermediaSupport,你能够控制Spring HATEOAS的配置。注意这会禁用上述的对ObjectMapper的自定义。

6.2. JAX-RS和Jersey

若是喜欢JAX-RS为REST端点提供的编程模型,你可使用可用的实现替代Spring MVC。若是在你的应用上下文中将Jersey 1.x和Apache Celtix的Servlet或Filter注册为一个@Bean,那它们工做的至关好。Jersey 2.x有一些原生的Spring支持,因此咱们会在Spring Boot为它提供自动配置支持,连同一个启动器(starter)。

想要开始使用Jersey 2.x只须要加入spring-boot-starter-jersey依赖,而后你须要一个ResourceConfig类型的@Bean,用于注册全部的端点(endpoints)。

  1.  
    @Component
  2.  
    public class JerseyConfig extends ResourceConfig {
  3.  
    public JerseyConfig() {
  4.  
    register(Endpoint.class);
  5.  
    }
  6.  
    }

全部注册的端点都应该被@Components和HTTP资源annotations(好比@GET)注解。

  1.  
    @Component
  2.  
    @Path("/hello")
  3.  
    public class Endpoint {
  4.  
    @GET
  5.  
    public String message() {
  6.  
    return "Hello";
  7.  
    }
  8.  
    }

因为Endpoint是一个Spring组件(@Component),因此它的生命周期受Spring管理,而且你可使用@Autowired添加依赖及使用@Value注入外部配置。Jersey servlet将被注册,并默认映射到/*。你能够将@ApplicationPath添加到ResourceConfig来改变该映射。

默认状况下,Jersey将在一个ServletRegistrationBean类型的@Bean中被设置成名称为jerseyServletRegistration的Servlet。经过建立本身的相同名称的bean,你能够禁止或覆盖这个bean。你也能够经过设置spring.jersey.type=filter来使用一个Filter代替Servlet(在这种状况下,被覆盖或替换的@Bean是jerseyFilterRegistration)。该servlet有@Order属性,你能够经过spring.jersey.filter.order进行设置。无论是Servlet仍是Filter注册均可以使用spring.jersey.init.*定义一个属性集合做为初始化参数传递过去。

这里有一个Jersey示例,你能够查看如何设置相关事项。

6.3. 内嵌servlet容器支持

Spring Boot支持内嵌的Tomcat, Jetty和Undertow服务器。多数开发者只须要使用合适的'Starter POM'来获取一个彻底配置好的实例便可。默认状况下,内嵌的服务器会在8080端口监听HTTP请求。

6.3.1. Servlets和Filters

当使用内嵌的servlet容器时,你能够直接将servlet和filter注册为Spring的beans。在配置期间,若是你想引用来自application.properties的值,这是很是方便的。默认状况下,若是上下文只包含单一的Servlet,那它将被映射到根路径(/)。在多Servlet beans的状况下,bean的名称将被用做路径的前缀。过滤器会被映射到/*。

若是基于约定(convention-based)的映射不够灵活,你可使用ServletRegistrationBean和FilterRegistrationBean类实现彻底的控制。若是你的bean实现了ServletContextInitializer接口,也能够直接注册它们。

6.3.2. EmbeddedWebApplicationContext

Spring Boot底层使用了一个新的ApplicationContext类型,用于对内嵌servlet容器的支持。EmbeddedWebApplicationContext是一个特殊类型的WebApplicationContext,它经过搜索一个单一的EmbeddedServletContainerFactory bean来启动本身。一般,TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory将被自动配置。

注:你一般不须要知道这些实现类。大多数应用将被自动配置,并根据你的行为建立合适的ApplicationContext和EmbeddedServletContainerFactory。

6.3.3. 自定义内嵌servlet容器

常见的Servlet容器设置能够经过Spring Environment属性进行配置。一般,你会把这些属性定义到application.properties文件中。 常见的服务器设置包括:

  1.  
    server.port - 进来的HTTP请求的监听端口号
  2.  
    server.address - 绑定的接口地址
  3.  
    server.sessionTimeout - session超时时间

具体参考ServerProperties。

编程方式的自定义 若是须要以编程的方式配置内嵌的servlet容器,你能够注册一个实现EmbeddedServletContainerCustomizer接口的Spring bean。EmbeddedServletContainerCustomizer提供对ConfigurableEmbeddedServletContainer的访问,ConfigurableEmbeddedServletContainer包含不少自定义的setter方法。

  1.  
    import org.springframework.boot.context.embedded.*;
  2.  
    import org.springframework.stereotype.Component;
  3.  
     
  4.  
    @Component
  5.  
    public class CustomizationBean implements EmbeddedServletContainerCustomizer {
  6.  
    @Override
  7.  
    public void customize(ConfigurableEmbeddedServletContainer container) {
  8.  
    container.setPort( 9000);
  9.  
    }
  10.  
    }

直接自定义ConfigurableEmbeddedServletContainer 若是上面的自定义手法过于受限,你能够本身注册TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory。

  1.  
    @Bean
  2.  
    public EmbeddedServletContainerFactory servletContainer() {
  3.  
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
  4.  
    factory.setPort( 9000);
  5.  
    factory.setSessionTimeout( 10, TimeUnit.MINUTES);
  6.  
    factory.addErrorPages( new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html");
  7.  
    return factory;
  8.  
    }

不少可选的配置都提供了setter方法,也提供了一些受保护的钩子方法以知足你的某些特殊需求。具体参考相关文档。

6.3.4. JSP的限制

在内嵌的servlet容器中运行一个Spring Boot应用时(并打包成一个可执行的存档archive),容器对JSP的支持有一些限制。

  1.  
    tomcat只支持war的打包方式,不支持可执行的jar。
  2.  
    内嵌的Jetty目前不支持JSPs。
  3.  
    Undertow不支持JSPs。

这里有个JSP示例,你能够查看如何设置相关事项。

相关文章
相关标签/搜索