代码结构示例

  1. com
  2. +- example
  3. +- myapplication
  4. +- Application.java
  5. |
  6. +- customer
  7. | +- Customer.java
  8. | +- CustomerController.java
  9. | +- CustomerService.java
  10. | +- CustomerRepository.java
  11. |
  12. +- order
  13. +- Order.java
  14. +- OrderController.java
  15. +- OrderService.java
  16. +- OrderRepository.java

The Application.java file would declare the main method, along with the basic @SpringBootApplication, as follows:

  1. package com.example.myapplication;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class Application {
  6. public static void main(String[] args) {
  7. SpringApplication.run(Application.class, args);
  8. }
  9. }

指定一个main函数入口类。

SpringBootApplication

用以指定启动类,同时指定已当前入口类的包路径为扫描路径。官方介绍是:

  1. * Indicates a {@link Configuration configuration} class that declares one or more
  2. * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
  3. * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
  4. * annotation that is equivalent to declaring {@code @Configuration},
  5. * {@code @EnableAutoConfiguration} and {@code @ComponentScan}.

指定一个配置类,用以声明一个或多个Bean,同时启用自动配置与组件扫描。
SpringBootApplication是一个便捷的注解,可以单独用:@EnableAutoConfiguration``@ComponentScan
来代替使用,往往不需要。

配置类

SpringBoot建议使用Java注解风格来配置Bean,用@Configuration来定义。

导入配置类(@Configuration)

不建议用@Configuration配置所有的Bean到一个类中,可以用@Import导入一个额外的配置类。
也可以用@ComponentScan来自动扫描Bean组件。

导入XML配置

推荐用@Configuration加@ImportResource来使用XML配置,用配置类统一管理。

  1. @Configuration
  2. @Import(AppConfig.class)
  3. @ImportResource("classpath:applicationContext.xml")
  4. public class AllConfig {
  5. }

启用自动配置

一般在入口类上打上@EnableAutoConfiguration 或@SpringBootApplication 便可开启自动配置功能,SpringBoot会自动扫描类路径下的jar,并做自动配置加载。

排查特殊自动配置类

  1. import org.springframework.boot.autoconfigure.*;
  2. import org.springframework.boot.autoconfigure.jdbc.*;
  3. @SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
  4. public class MyApplication {
  5. }

使用Spring与依赖注入

无缝集成Spring Framework All Feature

启用开发工具

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-devtools</artifactId>
  5. <optional>true</optional>
  6. </dependency>
  7. </dependencies>

用于自动重启,热部署场景

Web环境识别

SpringBoot根据类路径的Jar来推导应该Web环境类型

  • NONE

    不启用WebServer,并创建:AnnotationConfigApplicationContext

  • Servlet

    执行ClassUtils.ispresent(“org.springframework.web.servlet.DispatcherServlet”) 并创建:AnnotationConfigServletWebServerApplicationContext

  • Reactive

    执行ClassUtils.isPresent(“org.springframework.web.reactive.DispatcherHandler”) 并创建:AnnotationConfigReactiveWebServerApplicationContext

在单元测试中,建议添加:

setWebApplicationType(WebApplicationType.NONE)

使用ApplicationRunner 或CommandRunner

如果想在应用启动后执行一段代码,可以实现ApplicationRunner or CommandLineRunner interfaces. Both interfaces work in the same way and offer a single run method, which is called just before SpringApplication.run(…) completes.

  1. @Component
  2. public class OnAppStartedRunner implements ApplicationRunner {
  3. @Override
  4. public void run(ApplicationArguments args) throws Exception {
  5. System.err.println(args);
  6. }
  7. }
  8. @Component
  9. public class OnCommandLineRunner implements CommandLineRunner {
  10. @Override
  11. public void run(String... args) throws Exception {
  12. System.err.println(args);
  13. }
  14. }

如果配置了多个,希望有序执行时,则添加@Order或实现Order接口。

外部化配置

Application Property Files

SpringBoot会从以下目录加载application.properties文件:

  • 当前目录下的config目录
  • 当前目录
  • classpath目录下的config目录(二方包/三方jar)
  • classpath 跟目录(classes)

换言之,搜索路径:

  1. file:./config/
  2. file:./config/*/
  3. file:./
  4. classpath:/config/
  5. classpath:/

    Profile-specific Properties

    SpringBoot默认会加载application.properties,还会加载application-{profile}.properties。如果指定了spring.profiles.active, 则会加载对应的profile文件,如application-dev.properties。默认情况下,没有指定active, 则尝试加载application-default.properties.如果active指定多个,则都会加载。

使用YAML文件

Spring Framework provides two convenient classes that can be used to load YAML documents. The YamlPropertiesFactoryBean loads YAML as Properties and the YamlMapFactoryBean loads YAML as a Map. 默认加载为Properties。
如YAML文件内容为:

  1. environments:
  2. dev:
  3. url: https://dev.example.com
  4. name: Developer Setup
  5. prod:
  6. url: https://another.example.com
  7. name: My Cool App
  8. 对应属性文件为:
  9. environments.dev.url=https://dev.example.com
  10. environments.dev.name=Developer Setup
  11. environments.prod.url=https://another.example.com
  12. environments.prod.name=My Cool App

列表配置

  1. my:
  2. servers:
  3. - dev.example.com
  4. - another.example.com
  5. my.servers[0]=dev.example.com
  6. my.servers[1]=another.example.com

对应的属性绑定类为:

  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. }

注入YAML属性(直接使用@Value)

The YamlPropertySourceLoader class can be used to expose YAML as a PropertySource in the Spring Environment. Doing so lets you use the @Value annotation with placeholders syntax to access YAML properties.

Multi-profile YAML Documents

通过配置spring.profiles 来指定生效的YAML属性块。如果spring.profiles.active未指定任何profile,则加载全部默认的配置

  1. server:
  2. port:8080 ## 默认生效
  3. address: 192.168.1.100 ## 默认生效
  4. ---
  5. spring:
  6. profiles: development
  7. server:
  8. address: 127.0.0.1
  9. ---
  10. spring:
  11. profiles: production & eu-central
  12. server:
  13. address: 192.168.1.120

YAML的缺点

不能使用@PropertySource注解,但可以使用:@ConfigurationProperties。
属性值不能使用双引号,如下password会被注入为:"secret"

  1. server:
  2. port: 8000
  3. ---
  4. spring:
  5. profiles: "!test"
  6. security:
  7. user:
  8. password: "secret"

类型安全的配置属性

JavaBean属性绑定

  1. package com.example;
  2. import java.net.InetAddress;
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.List;
  6. import org.springframework.boot.context.properties.ConfigurationProperties;
  7. @ConfigurationProperties("acme")
  8. public class AcmeProperties {
  9. private boolean enabled;
  10. private InetAddress remoteAddress;
  11. private final Security security = new Security();
  12. public boolean isEnabled() { ... }
  13. public void setEnabled(boolean enabled) { ... }
  14. public InetAddress getRemoteAddress() { ... }
  15. public void setRemoteAddress(InetAddress remoteAddress) { ... }
  16. public Security getSecurity() { ... }
  17. public static class Security {
  18. private String username;
  19. private String password;
  20. private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
  21. public String getUsername() { ... }
  22. public void setUsername(String username) { ... }
  23. public String getPassword() { ... }
  24. public void setPassword(String password) { ... }
  25. public List<String> getRoles() { ... }
  26. public void setRoles(List<String> roles) { ... }
  27. }
  28. }

@ConfigurationProperties Validation

Spring Boot attempts to validate @ConfigurationProperties classes whenever they are annotated with Spring’s @Validated annotation. You can use JSR-303 javax.validation constraint annotations directly on your configuration class. To do so, ensure that a compliant JSR-303 implementation is on your classpath and then add constraint annotations to your fields, as shown in the following example:

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

@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

If you define a set of configuration keys for your own components, we recommend you group them in a POJO annotated with @ConfigurationProperties. Doing so will provide you with structured, type-safe object that you can inject into your own beans.
If you do want to use @Value, we recommend that you refer to property names using their canonical form (kebab-case using only lowercase letters). This will allow Spring Boot to use the same logic as it does when relaxed binding @ConfigurationProperties. For example, @Value("{demo.item-price}") will pick up demo.item-price and demo.itemPrice forms from the application.properties file, as well as DEMO_ITEMPRICE from the system environment. If you used @Value("{demo.itemPrice}") instead, demo.item-price and DEMO_ITEMPRICE would not be considered.
Finally, while you can write a SpEL expression in @Value, such expressions are not processed from application property files.

Profile

添加额外的Profiles

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

如果active的profile为prod,那么则会同时家长proddb,prodmq

JSON

SpringBoot支持:

  • jackson
  • gson
  • json-b

Jackson is the preferred and default library.