22 - Spring Boot:自动配置、Web 开发、DI/IoC
22 - Spring Boot:自动配置、Web 开发、DI/IoC
快速开始
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);
}
}
@SpringBootApplication 等价于:
@SpringBootConfiguration
@EnableAutoConfiguration // 自动配置
@ComponentScan // 包扫描
依赖注入(DI / IoC)
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
// 1. 定义 Bean
@Service
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
// 构造器注入(推荐)
public UserService(UserRepository userRepository, EmailService emailService) {
this.userRepository = userRepository;
this.emailService = emailService;
}
public User register(String name, String email) {
User user = new User(name, email);
userRepository.save(user);
emailService.sendWelcome(email);
return user;
}
}
// 2. Repository
@Repository
public class UserRepository {
private final Map<Long, User> db = new ConcurrentHashMap<>();
public void save(User user) {
db.put(user.getId(), user);
}
public Optional<User> findById(Long id) {
return Optional.ofNullable(db.get(id));
}
}
// 3. 配置类 Bean
@Configuration
public class AppConfig {
@Bean
@ConditionalOnMissingBean // 没有时才创建
public EmailService emailService() {
return new SmtpEmailService();
}
}
// 4. 注入方式
@RestController
public class UserController {
// 字段注入(不推荐)
// @Autowired private UserService userService;
// 构造器注入(推荐)
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
}
Bean 注解
| 注解 | 说明 | 使用场景 |
|---|---|---|
@Component | 通用组件 | 工具类 |
@Service | 业务层 | Service 类 |
@Repository | 数据层 | DAO 类 |
@Controller | 控制层 | MVC 控制器 |
@RestController | REST 控制器 | REST API |
@Configuration | 配置类 | 定义 Bean |
@Bean | 工厂方法 | 第三方库集成 |
RESTful Web 开发
import org.springframework.web.bind.annotation.*;
import org.springframework.http.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
// GET /api/users
@GetMapping
public List<User> list() {
return userService.findAll();
}
// GET /api/users/{id}
@GetMapping("/{id}")
public ResponseEntity<User> getById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// POST /api/users
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(@Valid @RequestBody CreateUserRequest request) {
return userService.create(request);
}
// PUT /api/users/{id}
@PutMapping("/{id}")
public User update(@PathVariable Long id,
@Valid @RequestBody UpdateUserRequest request) {
return userService.update(id, request);
}
// DELETE /api/users/{id}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
userService.delete(id);
}
}
请求参数处理
@RestController
@RequestMapping("/api/demo")
public class ParamController {
// 路径变量
@GetMapping("/users/{id}")
public String pathVar(@PathVariable Long id) { return "ID: " + id; }
// 查询参数
@GetMapping("/search")
public String queryParam(@RequestParam String keyword,
@RequestParam(defaultValue = "1") int page) {
return keyword + ", page " + page;
}
// 请求体
@PostMapping("/body")
public String body(@Valid @RequestBody UserDTO dto) { return dto.toString(); }
// 请求头
@GetMapping("/header")
public String header(@RequestHeader("Authorization") String token) {
return token;
}
}
全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("NOT_FOUND", ex.getMessage()));
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
String msg = ex.getBindingResult().getFieldErrors().stream()
.map(e -> e.getField() + ": " + e.getDefaultMessage())
.collect(Collectors.joining(", "));
return ResponseEntity.badRequest()
.body(new ErrorResponse("VALIDATION_ERROR", msg));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
return ResponseEntity.internalServerError()
.body(new ErrorResponse("INTERNAL_ERROR", "服务器内部错误"));
}
}
record ErrorResponse(String code, String message) {}
配置文件
# application.yml
server:
port: 8080
servlet:
context-path: /
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: ${DB_PASSWORD:default}
hikari:
maximum-pool-size: 10
jpa:
hibernate:
ddl-auto: update
show-sql: true
app:
name: My Application
jwt:
secret: ${JWT_SECRET}
expiration: 3600000
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private Jwt jwt = new Jwt();
// getters/setters
public static class Jwt {
private String secret;
private long expiration;
// getters/setters
}
}
⚠️ 注意事项
- 构造器注入优于字段注入 — 更容易测试,强制依赖不可为 null。
- 不要在 Service 层 catch 所有异常 — 使用全局异常处理器。
@Transactional只在 public 方法生效 — 自调用不会触发事务。- 配置敏感信息使用环境变量 — 不要硬编码密码。
💡 技巧
Profile 切换环境:
java -jar app.jar --spring.profiles.active=prodActuator 健康检查:
management: endpoints: web: exposure: include: health,info,metrics优雅关机:
server: shutdown: graceful spring: lifecycle: timeout-per-shutdown-phase: 30s
🏢 业务场景
- REST API 服务: 电商、社交、内容管理系统的后端。
- 微服务: Spring Cloud 生态中的独立服务。
- 后台管理: 前后端分离架构的后端部分。