Spring Boot 参考文档 #
1. 简介 #
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
1.1 主要特性 #
- 自动配置:根据项目依赖自动配置 Spring 应用
- 独立运行:内嵌 Tomcat、Jetty 或 Undertow,无需部署 WAR 文件
- 生产就绪:提供指标、健康检查和外部化配置
- 无代码生成和 XML 配置:减少样板代码,提高开发效率
2. 快速开始 #
2.1 系统要求 #
- JDK 17 或更高版本
- Maven 3.6+ 或 Gradle 7.5+
2.2 创建第一个 Spring Boot 应用 #
使用 Spring Initializr(推荐) #
- 访问 Spring Initializr
- 选择:
- 项目类型:Maven 或 Gradle
- 语言:Java
- Spring Boot 版本:最新稳定版
- 项目元数据:根据需要填写
- 添加依赖:
- Spring Web:用于创建 Web 应用
- 点击 “Generate” 下载项目
使用命令行 #
# 使用 Maven 创建 Spring Boot 应用
mvn archetype:generate -DgroupId=com.example -DartifactId=my-spring-boot-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
# 手动添加 Spring Boot 依赖到 pom.xml
2.3 项目结构 #
生成的项目结构如下:
my-spring-boot-app/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── myspringbootapp/
│ │ │ └── MySpringBootAppApplication.java
│ │ └── resources/
│ │ ├── application.properties
│ │ └── static/
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── myspringbootapp/
│ └── MySpringBootAppApplicationTests.java
├── pom.xml
└── README.md
2.4 启动应用 #
# 使用 Maven
cd my-spring-boot-app
mvn spring-boot:run
# 使用 Gradle
gradlew bootRun
应用将在 http://localhost:8080 启动。
3. 核心功能 #
3.1 自动配置 #
Spring Boot 的自动配置功能会根据项目中的依赖自动配置 Spring 应用上下文。例如,如果项目中包含 spring-boot-starter-web 依赖,Spring Boot 会自动配置 Tomcat 服务器和 Spring MVC。
3.2 启动器(Starters) #
启动器是一组方便的依赖描述符,可以一次性添加到项目中。例如:
<!-- Web 应用启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JPA 数据访问启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 测试启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
3.3 外部化配置 #
Spring Boot 允许将配置外部化,以便在不同环境中使用相同的应用代码。支持的配置源包括:
- application.properties
- application.yml
- 环境变量
- 命令行参数
例如,在 application.properties 中配置端口:
server.port=8081
或在 application.yml 中:
server:
port: 8081
3.4 配置属性 #
可以使用 @ConfigurationProperties 注解将外部配置映射到 Java 对象:
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
private String name;
private int version;
// getters and setters
}
然后在 application.properties 中配置:
myapp.name=My Application
myapp.version=1
4. 项目结构 #
Spring Boot 项目推荐使用以下结构:
src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── myapp/
│ │ ├── MyApplication.java # 应用入口
│ │ ├── config/ # 配置类
│ │ ├── controller/ # 控制器
│ │ ├── service/ # 服务层
│ │ ├── repository/ # 数据访问层
│ │ └── model/ # 数据模型
│ └── resources/
│ ├── application.properties # 主配置文件
│ ├── application-dev.properties # 开发环境配置
│ ├── application-prod.properties # 生产环境配置
│ ├── static/ # 静态资源
│ ├── templates/ # 模板文件
│ └── data.sql # 初始化数据
└── test/
└── java/
└── com/
└── example/
└── myapp/
├── controller/ # 控制器测试
├── service/ # 服务层测试
└── repository/ # 数据访问层测试
4.1 应用入口类 #
应用入口类使用 @SpringBootApplication 注解:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@SpringBootApplication 是一个复合注解,包含:
@Configuration:标记该类为配置类@EnableAutoConfiguration:启用自动配置@ComponentScan:启用组件扫描
5. 配置管理 #
5.1 多环境配置 #
Spring Boot 支持多环境配置,可以通过 spring.profiles.active 属性指定当前环境:
# application.properties
spring.profiles.active=dev
或通过命令行参数:
java -jar myapp.jar --spring.profiles.active=prod
5.2 配置优先级 #
Spring Boot 配置的优先级从高到低依次为:
- 命令行参数
- 环境变量
- Java 系统属性
- 应用配置文件(application-{profile}.properties/yml)
- 主应用配置文件(application.properties/yml)
- 默认配置
5.3 配置加密 #
对于敏感配置,可以使用 Spring Cloud Config Server 或 Jasypt Spring Boot 进行加密:
<!-- Jasypt Spring Boot 依赖 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
6. Web 开发 #
6.1 Spring MVC #
Spring Boot 提供了对 Spring MVC 的自动配置,包括:
- 视图解析器配置
- 静态资源处理
- 消息转换器配置
- 异常处理
6.2 REST API 开发 #
使用 @RestController 注解创建 REST API:
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User createUser(@RequestBody User user) {
return userService.save(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
// 实现更新逻辑
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteUser(@PathVariable Long id) {
userService.deleteById(id);
}
}
6.3 异常处理 #
使用 @ControllerAdvice 全局处理异常:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) {
ErrorResponse error = new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred");
return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
7. 数据访问 #
7.1 Spring Data JPA #
Spring Boot 对 Spring Data JPA 提供了自动配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
配置数据库连接:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.h2.console.enabled=true
创建实体类:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false, unique = true)
private String email;
// getters and setters
}
创建仓库接口:
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByNameContaining(String name);
Optional<User> findByEmail(String email);
}
7.2 事务管理 #
使用 @Transactional 注解管理事务:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public User save(User user) {
return userRepository.save(user);
}
@Transactional(readOnly = true)
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
@Transactional
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
8. 测试 #
Spring Boot 提供了强大的测试支持:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
8.1 单元测试 #
使用 JUnit 5 进行单元测试:
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class UserServiceTest {
@MockBean
private UserRepository userRepository;
@Autowired
private UserService userService;
@Test
public void testFindById() {
// 准备数据
User user = new User();
user.setId(1L);
user.setName("Test User");
// 模拟行为
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
// 执行测试
Optional<User> foundUser = userService.findById(1L);
// 验证结果
assertTrue(foundUser.isPresent());
assertEquals("Test User", foundUser.get().getName());
}
}
8.2 集成测试 #
测试 REST API:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGetAllUsers() {
User[] users = restTemplate.getForObject("/api/users", User[].class);
assertNotNull(users);
assertTrue(users.length > 0);
}
@Test
public void testCreateUser() {
User newUser = new User();
newUser.setName("New User");
newUser.setEmail("new@example.com");
User createdUser = restTemplate.postForObject("/api/users", newUser, User.class);
assertNotNull(createdUser);
assertNotNull(createdUser.getId());
assertEquals("New User", createdUser.getName());
}
}
9. 生产就绪特性 #
9.1 健康检查 #
Spring Boot Actuator 提供了健康检查端点:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置健康检查:
management.endpoints.web.exposure.include=health,info
management.endpoint.health.show-details=always
访问健康检查端点:http://localhost:8080/actuator/health
9.2 指标监控 #
Actuator 提供了各种指标,如 CPU 使用率、内存使用情况等:
management.endpoints.web.exposure.include=health,info,metrics
访问指标端点:http://localhost:8080/actuator/metrics
9.3 外部化配置 #
在生产环境中,可以使用环境变量或命令行参数覆盖配置:
java -jar myapp.jar --spring.profiles.active=prod --server.port=8080
或使用 Docker:
FROM openjdk:17-jdk-slim
COPY target/myapp.jar app.jar
ENV SPRING_PROFILES_ACTIVE=prod
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
10. 部署 #
10.1 打包应用 #
使用 Maven 打包:
mvn clean package
或使用 Gradle:
gradlew clean build
10.2 运行打包后的应用 #
java -jar target/myapp-0.0.1-SNAPSHOT.jar
10.3 部署到容器 #
创建 Dockerfile:
FROM openjdk:17-jdk-slim
LABEL maintainer="your-email@example.com"
WORKDIR /app
COPY target/myapp-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
构建 Docker 镜像:
docker build -t myapp:1.0 .
运行 Docker 容器:
docker run -d -p 8080:8080 myapp:1.0
10.4 部署到 Kubernetes #
创建 deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
---
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
部署到 Kubernetes:
kubectl apply -f deployment.yaml
11. 最佳实践 #
11.1 项目结构 #
- 遵循 Maven/Gradle 标准目录结构
- 使用包结构组织代码(按功能或分层)
- 保持应用入口类简洁
11.2 配置管理 #
- 使用多环境配置文件
- 避免硬编码配置
- 使用
@ConfigurationProperties管理配置 - 对敏感配置进行加密
11.3 代码质量 #
- 遵循 Spring 命名约定
- 使用 Lombok 减少样板代码
- 编写单元测试和集成测试
- 使用代码质量工具(如 SonarQube)
11.4 性能优化 #
- 启用缓存
- 优化数据库查询
- 使用连接池
- 启用 GZIP 压缩
- 配置适当的 JVM 参数
11.5 安全 #
- 启用 Spring Security
- 使用 HTTPS
- 实现认证和授权
- 防止常见安全漏洞(如 CSRF、XSS)
- 定期更新依赖
12. 常见问题 #
12.1 如何更改应用端口? #
在 application.properties 中配置:
server.port=8081
12.2 如何配置数据源? #
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
12.3 如何启用热部署? #
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
12.4 如何查看应用日志? #
配置日志级别:
logging.level.root=INFO
logging.level.com.example.myapp=DEBUG
12.5 如何处理跨域请求? #
使用 @CrossOrigin 注解:
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*")
public class UserController {
// ...
}
或全局配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*");
}
}
13. 总结 #
Spring Boot 是一个强大的框架,可以大大简化 Spring 应用的开发和部署。通过自动配置、启动器和生产就绪特性,开发人员可以快速构建高质量的应用程序。遵循最佳实践可以确保应用的可维护性、性能和安全性。
要了解更多信息,请访问 Spring Boot 官方文档。