代码结构示例
com
+- example
+- myapplication
+- Application.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
The Application.java
file would declare the main
method, along with the basic @SpringBootApplication
, as follows:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
指定一个main函数入口类。
SpringBootApplication
用以指定启动类,同时指定已当前入口类的包路径为扫描路径。官方介绍是:
* Indicates a {@link Configuration configuration} class that declares one or more
* {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
* auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
* annotation that is equivalent to declaring {@code @Configuration},
* {@code @EnableAutoConfiguration} and {@code @ComponentScan}.
指定一个配置类,用以声明一个或多个Bean,同时启用自动配置与组件扫描。
SpringBootApplication是一个便捷的注解,可以单独用:@EnableAutoConfiguration``@ComponentScan
来代替使用,往往不需要。
配置类
SpringBoot建议使用Java注解风格来配置Bean,用@Configuration来定义。
导入配置类(@Configuration)
不建议用@Configuration配置所有的Bean到一个类中,可以用@Import导入一个额外的配置类。
也可以用@ComponentScan来自动扫描Bean组件。
导入XML配置
推荐用@Configuration加@ImportResource来使用XML配置,用配置类统一管理。
@Configuration
@Import(AppConfig.class)
@ImportResource("classpath:applicationContext.xml")
public class AllConfig {
}
启用自动配置
一般在入口类上打上@EnableAutoConfiguration
或@SpringBootApplication 便可开启自动配置功能,SpringBoot会自动扫描类路径下的jar,并做自动配置加载。
排查特殊自动配置类
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class MyApplication {
}
使用Spring与依赖注入
无缝集成Spring Framework All Feature
启用开发工具
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</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.
@Component
public class OnAppStartedRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.err.println(args);
}
}
@Component
public class OnCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.err.println(args);
}
}
如果配置了多个,希望有序执行时,则添加@Order或实现Order接口。
外部化配置
Application Property Files
SpringBoot会从以下目录加载application.properties文件:
- 当前目录下的config目录
- 当前目录
- classpath目录下的config目录(二方包/三方jar)
- classpath 跟目录(classes)
换言之,搜索路径:
file:./config/
file:./config/*/
file:./
classpath:/config/
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文件内容为:
environments:
dev:
url: https://dev.example.com
name: Developer Setup
prod:
url: https://another.example.com
name: My Cool App
对应属性文件为:
environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App
列表配置
my:
servers:
- dev.example.com
- another.example.com
my.servers[0]=dev.example.com
my.servers[1]=another.example.com
对应的属性绑定类为:
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
注入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,则加载全部默认的配置
server:
port:8080 ## 默认生效
address: 192.168.1.100 ## 默认生效
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production & eu-central
server:
address: 192.168.1.120
YAML的缺点
不能使用@PropertySource注解,但可以使用:@ConfigurationProperties。
属性值不能使用双引号,如下password会被注入为:"secret"
server:
port: 8000
---
spring:
profiles: "!test"
security:
user:
password: "secret"
类型安全的配置属性
JavaBean属性绑定
package com.example;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("acme")
public class AcmeProperties {
private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { ... }
public void setEnabled(boolean enabled) { ... }
public InetAddress getRemoteAddress() { ... }
public void setRemoteAddress(InetAddress remoteAddress) { ... }
public Security getSecurity() { ... }
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
public String getUsername() { ... }
public void setUsername(String username) { ... }
public String getPassword() { ... }
public void setPassword(String password) { ... }
public List<String> getRoles() { ... }
public void setRoles(List<String> roles) { ... }
}
}
@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:
@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
@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
---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
- proddb
- prodmq
如果active的profile为prod,那么则会同时家长proddb,prodmq
JSON
SpringBoot支持:
- jackson
- gson
- json-b
Jackson is the preferred and default library.