Spring Boot

官网

https://spring.io/projects/spring-boot

简介

特性

  • 创建独立的Spring应用

  • 内嵌Tomcat、Jetty、Undertow容器 (不需要部署 WAR 文件)

  • 提供启动器来简化配置和依赖

  • 自动配置Spring和三方库

  • 提供产品级别特性,比如度量指标、健康检查、外部配置

  • 几乎没有代码生成,不需要XML配置文件

快速指南

 

文档

https://docs.spring.io/spring-boot/docs/current/reference/html/

Maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>

    <!-- Additional lines to be added here... -->

</project>

依赖管理

加入web启动器,Spring Boot自动加入Spring、Spring MVC、Jackson、Tomcat等相关依赖。

版本由Spring Boot管理。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Maven插件

https://docs.spring.io/spring-boot/docs/2.7.0/maven-plugin/reference/htmlsingle/

此插件会重新打包jar,将所有依赖jar和配置文件打包,并重新组织文件结构。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
mvn spring-boot:help
mvn spring-boot:run

启动器starter

https://start.spring.io/

Starters are a set of convenient dependency descriptors that you can include in your application. 

Name Description

spring-boot-starter

Core starter, including auto-configuration support, logging and YAML

spring-boot-starter-activemq

Starter for JMS messaging using Apache ActiveMQ

spring-boot-starter-amqp

Starter for using Spring AMQP and Rabbit MQ

spring-boot-starter-aop

Starter for aspect-oriented programming with Spring AOP and AspectJ

spring-boot-starter-artemis

Starter for JMS messaging using Apache Artemis

spring-boot-starter-batch

Starter for using Spring Batch

spring-boot-starter-cache

Starter for using Spring Framework’s caching support

spring-boot-starter-data-cassandra

Starter for using Cassandra distributed database and Spring Data Cassandra

spring-boot-starter-data-cassandra-reactive

Starter for using Cassandra distributed database and Spring Data Cassandra Reactive

spring-boot-starter-data-couchbase

Starter for using Couchbase document-oriented database and Spring Data Couchbase

spring-boot-starter-data-couchbase-reactive

Starter for using Couchbase document-oriented database and Spring Data Couchbase Reactive

spring-boot-starter-data-elasticsearch

Starter for using Elasticsearch search and analytics engine and Spring Data Elasticsearch

spring-boot-starter-data-jdbc

Starter for using Spring Data JDBC

spring-boot-starter-data-jpa

Starter for using Spring Data JPA with Hibernate

spring-boot-starter-data-ldap

Starter for using Spring Data LDAP

spring-boot-starter-data-mongodb

Starter for using MongoDB document-oriented database and Spring Data MongoDB

spring-boot-starter-data-mongodb-reactive

Starter for using MongoDB document-oriented database and Spring Data MongoDB Reactive

spring-boot-starter-data-neo4j

Starter for using Neo4j graph database and Spring Data Neo4j

spring-boot-starter-data-r2dbc

Starter for using Spring Data R2DBC

spring-boot-starter-data-redis

Starter for using Redis key-value data store with Spring Data Redis and the Lettuce client

spring-boot-starter-data-redis-reactive

Starter for using Redis key-value data store with Spring Data Redis reactive and the Lettuce client

spring-boot-starter-data-rest

Starter for exposing Spring Data repositories over REST using Spring Data REST

spring-boot-starter-freemarker

Starter for building MVC web applications using FreeMarker views

spring-boot-starter-graphql

Starter for building GraphQL applications with Spring GraphQL

spring-boot-starter-groovy-templates

Starter for building MVC web applications using Groovy Templates views

spring-boot-starter-hateoas

Starter for building hypermedia-based RESTful web application with Spring MVC and Spring HATEOAS

spring-boot-starter-integration

Starter for using Spring Integration

spring-boot-starter-jdbc

Starter for using JDBC with the HikariCP connection pool

spring-boot-starter-jersey

Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to spring-boot-starter-web

spring-boot-starter-jooq

Starter for using jOOQ to access SQL databases with JDBC. An alternative to spring-boot-starter-data-jpa or spring-boot-starter-jdbc

spring-boot-starter-json

Starter for reading and writing json

spring-boot-starter-jta-atomikos

Starter for JTA transactions using Atomikos

spring-boot-starter-mail

Starter for using Java Mail and Spring Framework’s email sending support

spring-boot-starter-mustache

Starter for building web applications using Mustache views

spring-boot-starter-oauth2-client

Starter for using Spring Security’s OAuth2/OpenID Connect client features

spring-boot-starter-oauth2-resource-server

Starter for using Spring Security’s OAuth2 resource server features

spring-boot-starter-quartz

Starter for using the Quartz scheduler

spring-boot-starter-rsocket

Starter for building RSocket clients and servers

spring-boot-starter-security

Starter for using Spring Security

spring-boot-starter-test

Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito

spring-boot-starter-thymeleaf

Starter for building MVC web applications using Thymeleaf views

spring-boot-starter-validation

Starter for using Java Bean Validation with Hibernate Validator

spring-boot-starter-web

Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container

spring-boot-starter-web-services

Starter for using Spring Web Services

spring-boot-starter-webflux

Starter for building WebFlux applications using Spring Framework’s Reactive Web support

spring-boot-starter-websocket

Starter for building WebSocket applications using Spring Framework’s WebSocket support

spring-boot-starter-actuator

Starter for using Spring Boot’s Actuator which provides production ready features to help you monitor and manage your application

Name Description

spring-boot-starter-jetty

Starter for using Jetty as the embedded servlet container. An alternative to spring-boot-starter-tomcat

spring-boot-starter-log4j2

Starter for using Log4j2 for logging. An alternative to spring-boot-starter-logging

spring-boot-starter-logging

Starter for logging using Logback. Default logging starter

spring-boot-starter-reactor-netty

Starter for using Reactor Netty as the embedded reactive HTTP server.

spring-boot-starter-tomcat

Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web

spring-boot-starter-undertow

Starter for using Undertow as the embedded servlet container. An alternative to spring-boot-starter-tomcat

示例代码

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableAutoConfiguration
public class MyApplication {

    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

@SpringBootApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Same as @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  • @ComponentScan: 扫描被@Component (@Repository,@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。
  • @Configuration:允许在 Spring 上下文中注册额外的 bean 或导入其他配置类

配置类

@Configuration

@Import

@ComponentScan

@ImportResource

自动配置

@AutoConfiguration

@ConditionalOnClass / @ConditionalOnMissingClass

@ConditionalOnBean / @ConditionalOnMissingBean

@AutoConfiguration
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public SomeService someService() {
        return new SomeService();
    }

}

@ConditionalOnProperty

@ConditionalOnResource

@ConditionalOnWebApplication / @ConditionalOnNotWebApplication

@ConditionalOnExpression

Application Events and Listeners

SpringApplication.addListeners(…​)

SpringApplicationBuilder.listeners(…​)

META-INF/spring.factories

  org.springframework.context.ApplicationListener=com.example.project.MyListener
  1. ApplicationStartingEvent
  2. ApplicationEnvironmentPreparedEvent
  3. ApplicationContextInitializedEvent
  4. ApplicationPreparedEvent
  5. WebServerInitializedEvent
  6. ContextRefreshedEvent
  7. ApplicationStartedEvent
  8. AvailabilityChangeEvent
  9. ApplicationReadyEvent
  10. AvailabilityChangeEvent
  11. ApplicationFailedEvent

 

CommandLineRunner and ApplicationRunner

 

外部配置

  1. Default properties (specified by setting SpringApplication.setDefaultProperties).
  2. @PropertySource annotations on your @Configuration classes.
  3. Config data (such as application.properties files).
  4. RandomValuePropertySource that has properties only in random.*.
  5. OS environment variables.
  6. Java System properties (System.getProperties()).
  7. JNDI attributes from java:comp/env.
  8. ServletContext init parameters.
  9. ServletConfig init parameters.
  10. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
  11. Command line arguments.
  12. properties attribute on your tests. Available on @SpringBootTest
  13. @TestPropertySource annotations on your tests.
  14. Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active.

Config data files are considered in the following order:

  1. Application properties packaged inside your jar (application.properties and YAML variants).

  2. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).

  3. Application properties outside of your packaged jar (application.properties and YAML variants).

  4. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).

外部配置文件

Spring Boot will automatically find and load application.properties and application.yaml files from the following locations when your application starts:

  1. From the classpath

    1. The classpath root

    2. The classpath /config package

  2. From the current directory

    1. The current directory

    2. The /config subdirectory in the current directory

    3. Immediate child directories of the /config subdirectory: config/*/

spring.application.name=myapp
spring.config.import=optional:file:./dev.properties

Property Placeholders

app:
  name: "MyApp"
  description: "${app.name} is a Spring Boot application written by ${username:Unknown}"

Multi-Document Files

spring:
  application:
    name: "MyApp"
---
spring:
  application:
    name: "MyCloudApp"
  config:
    activate:
      on-cloud-platform: "kubernetes"
myprop:
  "always-set"
---
spring:
  config:
    activate:
      on-cloud-platform: "kubernetes"
      on-profile: "prod | staging"
myotherprop: "sometimes-set"

随机值

my:
  secret: "${random.value}"
  number: "${random.int}"
  bignumber: "${random.long}"
  uuid: "${random.uuid}"
  number-less-than-ten: "${random.int(10)}"
  number-in-range: "${random.int[1024,65536]}"

使用配置

@Value

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...
}

SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar

java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar

java -jar app.jar --name="Spring"

Environment

    @Autowired
    private Environment environment;

    public String getServerPort() {
        return environment.getProperty("server.port");
    }

@ConfigurationProperties

@ConfigurationProperties("my.service")
public class MyProperties {
    private boolean enabled;
    private InetAddress remoteAddress;
    private final Security security = new Security();

    // getters / setters...

    public static class Security {
        private String username;
        private String password;
        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

        // getters / setters...

    }
}

Bean

@Configuration(proxyBeanMethods = false)
public class ThirdPartyConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "another")
    public AnotherComponent anotherComponent() {
        return new AnotherComponent();
    }

}

@ConstructorBinding

@ConstructorBinding
@ConfigurationProperties("my.service")
public class MyProperties {

    // fields...

    public MyProperties(boolean enabled, InetAddress remoteAddress, Security security) {
        this.enabled = enabled;
        this.remoteAddress = remoteAddress;
        this.security = security;
    }

    // getters...

    public static class Security {

        // fields...

        public Security(String username, String password, @DefaultValue("USER") List<String> roles) {
            this.username = username;
            this.password = password;
            this.roles = roles;
        }

        // getters...

    }
}

@EnableConfigurationProperties

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SomeProperties.class)
public class MyConfiguration {

}

@ConfigurationPropertiesScan

@SpringBootApplication
@ConfigurationPropertiesScan({ "com.example.app", "com.example.another" })
public class MyApplication {

}

Inject

@Service
public class MyService {
    private final SomeProperties properties;

    public MyService(SomeProperties properties) {
        this.properties = properties;
    }

    public void openConnection() {
        Server server = new Server(this.properties.getRemoteAddress());
        server.start();
        // ...
    }
}

Relaxed Binding

Property Note

my.main-project.person.first-name

Kebab case, which is recommended for use in .properties and .yml files.

my.main-project.person.firstName

Standard camel case syntax.

my.main-project.person.first_name

Underscore notation, which is an alternative format for use in .properties and .yml files.

MY_MAINPROJECT_PERSON_FIRSTNAME

Upper case format, which is recommended when using system environment variables.

Property Source Simple List

Properties Files

Camel case, kebab case, or underscore notation

Standard list syntax using [ ] or comma-separated values

YAML Files

Camel case, kebab case, or underscore notation

Standard YAML list syntax or comma-separated values

Environment Variables

Upper case format with underscore as the delimiter (see Binding from Environment Variables).

Numeric values surrounded by underscores (see Binding from Environment Variables)

System properties

Camel case, kebab case, or underscore notation

Standard list syntax using [ ] or comma-separated values

Converting Durations

  • A regular long representation (using milliseconds as the default unit unless a @DurationUnit has been specified)

  • The standard ISO-8601 format used by java.time.Duration

  • A more readable format where the value and the unit are coupled (10s means 10 seconds)

To specify a session timeout of 30 seconds, 30PT30S and 30s are all equivalent. A read timeout of 500ms can be specified in any of the following form: 500PT0.5S and 500ms.

Converting Data Sizes

  • A regular long representation (using bytes as the default unit unless a @DataSizeUnit has been specified)

  • A more readable format where the value and the unit are coupled (10MB means 10 megabytes)

To specify a buffer size of 10 megabytes, 10 and 10MB are equivalent. A size threshold of 256 bytes can be specified as 256 or 256B.

@ConfigurationProperties vs. @Value

The @Value annotation is a core container feature, and it does not provide the same features as type-safe configuration properties. The following table summarizes the features that are supported by @ConfigurationProperties and @Value:

Feature @ConfigurationProperties @Value

Relaxed binding

Yes

Limited (see note below)

Meta-data support

Yes

No

SpEL evaluation

No

Yes

Profiles

Spring Profiles provide a way to segregate parts of your application configuration and make it be available only in certain environments. Any @Component@Configuration or @ConfigurationProperties can be marked with @Profile to limit when it is loaded, as shown in the following example:

@Configuration(proxyBeanMethods = false)
@Profile("production")
public class ProductionConfiguration {

    // ...

}

启用

spring:
  profiles:
    active: "dev,hsqldb"

You could also specify it on the command line by using the following switch: --spring.profiles.active=dev,hsqldb.

日志

文件输出

logging.file.name logging.file.path Example Description

(none)

(none)

 

Console only logging.

Specific file

(none)

my.log

Writes to the specified log file. Names can be an exact location or relative to the current directory.

(none)

Specific directory

/var/log

Writes spring.log to the specified directory. Names can be an exact location or relative to the current directory.

Log files rotate when they reach 10 MB and, as with console output, ERROR-level, WARN-level, and INFO-level messages are logged by default.
 

日志级别

logging:
  level:
    root: info
    org.springframework.web: debug
    org.hibernate: error

定制日志配置

Logging System Customization

Logback

logback-spring.xmllogback-spring.groovylogback.xml, or logback.groovy

Log4j2

log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)

logging.properties

Logback Extensions

logback-spring.xml

Profile-specific Configuration

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

Environment Properties

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
        defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
    <remoteHost>${fluentHost}</remoteHost>
    ...
</appender>

JSON

Jackson

测试

The spring-boot-starter-test “Starter” (in the test scope) contains the following provided libraries:

  • JUnit 5: The de-facto standard for unit testing Java applications.

  • Spring Test & Spring Boot Test: Utilities and integration test support for Spring Boot applications.

  • AssertJ: A fluent assertion library.

  • Hamcrest: A library of matcher objects (also known as constraints or predicates).

  • Mockito: A Java mocking framework.

  • JSONassert: An assertion library for JSON.

  • JsonPath: XPath for JSON.

@SpringBootTest

@TestConfiguration

@AutoConfigureWebTestClient

@SpringBootTest
@AutoConfigureWebTestClient
class MyMockWebTestClientTests {
    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient
            .get().uri("/")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Hello World");
    }
}

Testing with a running server

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortWebTestClientTests {
    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient
            .get().uri("/")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Hello World");
    }
}

@MockBean

@SpringBootTest
class MyTests {

    @Autowired
    private Reverser reverser;

    @MockBean
    private RemoteService remoteService;

    @Test
    void exampleTest() {
        given(this.remoteService.getValue()).willReturn("spring");
        String reverse = this.reverser.getReverseValue(); // Calls injected RemoteService
        assertThat(reverse).isEqualTo("gnirps");
    }

}

@WebFluxTest

@WebFluxTest(UserVehicleController.class)
class MyControllerTests {

    @Autowired
    private WebTestClient webClient;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
            .willReturn(new VehicleDetails("Honda", "Civic"));
        this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN).exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Honda Civic");
    }

}