快速构建生产级Spring应用
Spring Boot 是基于 Spring 框架的快速开发脚手架,旨在简化 Spring 应用的初始搭建和开发过程。它采用"约定优于配置"的理念,让开发者能够快速创建独立的、生产级的 Spring 应用。
传统 Spring 应用需要大量 XML 配置,而 Spring Boot 通过自动配置和起步依赖,让开发者专注于业务逻辑,大大提高开发效率。
| 特性 | Spring | Spring Boot |
|---|---|---|
| 配置方式 | 大量 XML 或 Java 配置 | 自动配置,极少配置 |
| 依赖管理 | 手动管理版本 | Starter 统一管理 |
| 服务器 | 需要外部服务器 | 内嵌服务器 |
| 部署方式 | WAR 包部署 | JAR 包独立运行 |
| 开发效率 | 配置繁琐 | 快速开发 |
让我们通过实践创建第一个 Spring Boot 应用,体验其简洁性。
使用 Spring Initializr(https://start.spring.io/)或 IDE 创建项目。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<!-- 继承 Spring Boot 父项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-demo</artifactId>
<version>1.0.0</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Web 起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Spring Boot Maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>Spring Boot 应用的入口是一个带有 @SpringBootApplication 注解的主类。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Spring Boot 主启动类
* @SpringBootApplication 是一个组合注解,包含:
* - @SpringBootConfiguration:标记为配置类
* - @EnableAutoConfiguration:启用自动配置
* - @ComponentScan:启用组件扫描
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 启动 Spring Boot 应用
SpringApplication.run(Application.class, args);
}
}这个注解等同于以下三个注解的组合:
创建一个简单的 REST 控制器,处理 HTTP 请求。
package com.example.controller;
import org.springframework.web.bind.annotation.*;
@RestController // @Controller + @ResponseBody
@RequestMapping("/api")
public class HelloController {
/**
* 简单的 GET 请求
* 访问:http://localhost:8080/api/hello
*/
@GetMapping("/hello")
public String hello() {
return "Hello, Spring Boot!";
}
/**
* 带路径变量的请求
* 访问:http://localhost:8080/api/hello/张三
*/
@GetMapping("/hello/{name}")
public String helloName(@PathVariable String name) {
return "Hello, " + name + "!";
}
/**
* 带请求参数的请求
* 访问:http://localhost:8080/api/greet?name=李四
*/
@GetMapping("/greet")
public String greet(@RequestParam String name) {
return "Greetings, " + name + "!";
}
/**
* POST 请求,接收 JSON 数据
*/
@PostMapping("/user")
public User createUser(@RequestBody User user) {
user.setId(1L);
return user;
}
}
// 用户实体类
class User {
private Long id;
private String name;
private Integer age;
// getter/setter
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
}Spring Boot 支持两种配置文件格式:application.properties 和 application.yml。
# 服务器端口
server.port=8080
# 应用名称
spring.application.name=springboot-demo
# 日志级别
logging.level.root=INFO
logging.level.com.example=DEBUG
# 数据源配置
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# 服务器配置
server:
port: 8080
servlet:
context-path: /
# 应用配置
spring:
application:
name: springboot-demo
# 数据源配置
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
# JPA 配置
jpa:
show-sql: true
hibernate:
ddl-auto: update
# 日志配置
logging:
level:
root: INFO
com.example: DEBUG直接运行 Application 类的 main 方法。
# 编译打包
mvn clean package
# 运行应用
java -jar target/springboot-demo-1.0.0.jar
# 或者使用 Maven 插件直接运行
mvn spring-boot:run# 使用不同的配置文件
java -jar app.jar --spring.profiles.active=prod
# 覆盖端口
java -jar app.jar --server.port=9090 . ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.0)
2024-11-23 11:15:30.123 INFO 12345 --- [main] com.example.Application
: Started Application in 2.345 seconds访问:http://localhost:8080/api/hello
# GET 请求
curl http://localhost:8080/api/hello
# 带参数的 GET 请求
curl http://localhost:8080/api/greet?name=张三
# POST 请求
curl -X POST http://localhost:8080/api/user \
-H "Content-Type: application/json" \
-d '{"name":"李四","age":25}'package com.example.controller;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testHello() throws Exception {
mockMvc.perform(get("/api/hello"))
.andExpect(status().isOk())
.andExpect(content().string("Hello, Spring Boot!"));
}
@Test
public void testHelloName() throws Exception {
mockMvc.perform(get("/api/hello/张三"))
.andExpect(status().isOk())
.andExpect(content().string("Hello, 张三!"));
}
}