spring-boot

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Spring Boot

Spring Boot

Java framework for building production-ready microservices.
用于构建生产就绪型微服务的Java框架。

When to Use

适用场景

  • Enterprise Java applications
  • Microservices architecture
  • REST APIs with Java/Kotlin
  • Cloud-native applications
  • 企业级Java应用
  • 微服务架构
  • 基于Java/Kotlin的REST API
  • 云原生应用

Quick Start

快速开始

java
@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return userService.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) {
        User user = userService.create(request);
        return ResponseEntity.created(URI.create("/api/users/" + user.getId())).body(user);
    }
}
java
@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return userService.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) {
        User user = userService.create(request);
        return ResponseEntity.created(URI.create("/api/users/" + user.getId())).body(user);
    }
}

Core Concepts

核心概念

Dependency Injection

依赖注入

java
@Service
@Transactional(readOnly = true)
public class UserService {
    private final UserRepository repository;
    private final PasswordEncoder passwordEncoder;

    public UserService(UserRepository repository, PasswordEncoder passwordEncoder) {
        this.repository = repository;
        this.passwordEncoder = passwordEncoder;
    }

    @Transactional
    public User create(CreateUserRequest request) {
        User user = new User();
        user.setEmail(request.email());
        user.setPassword(passwordEncoder.encode(request.password()));
        return repository.save(user);
    }

    public Optional<User> findById(Long id) {
        return repository.findById(id);
    }
}
java
@Service
@Transactional(readOnly = true)
public class UserService {
    private final UserRepository repository;
    private final PasswordEncoder passwordEncoder;

    public UserService(UserRepository repository, PasswordEncoder passwordEncoder) {
        this.repository = repository;
        this.passwordEncoder = passwordEncoder;
    }

    @Transactional
    public User create(CreateUserRequest request) {
        User user = new User();
        user.setEmail(request.email());
        user.setPassword(passwordEncoder.encode(request.password()));
        return repository.save(user);
    }

    public Optional<User> findById(Long id) {
        return repository.findById(id);
    }
}

Spring Data JPA

Spring Data JPA

java
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String email;

    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
    private List<Post> posts = new ArrayList<>();
}

public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);

    @Query("SELECT u FROM User u WHERE u.active = true")
    List<User> findActiveUsers();
}
java
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String email;

    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
    private List<Post> posts = new ArrayList<>();
}

public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);

    @Query("SELECT u FROM User u WHERE u.active = true")
    List<User> findActiveUsers();
}

Common Patterns

常见模式

Exception Handling

异常处理

java
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
        return ResponseEntity.status(404)
            .body(new ErrorResponse(ex.getMessage()));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
        Map<String, String> errors = ex.getBindingResult().getFieldErrors().stream()
            .collect(Collectors.toMap(
                FieldError::getField,
                FieldError::getDefaultMessage
            ));
        return ResponseEntity.badRequest().body(new ErrorResponse("Validation failed", errors));
    }
}
java
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
        return ResponseEntity.status(404)
            .body(new ErrorResponse(ex.getMessage()));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
        Map<String, String> errors = ex.getBindingResult().getFieldErrors().stream()
            .collect(Collectors.toMap(
                FieldError::getField,
                FieldError::getDefaultMessage
            ));
        return ResponseEntity.badRequest().body(new ErrorResponse("Validation failed", errors));
    }
}

Best Practices

最佳实践

Do:
  • Use constructor injection
  • Use Spring Data repositories
  • Implement proper error handling
  • Use profiles for environments
Don't:
  • Use field injection (@Autowired on fields)
  • Expose entities directly
  • Skip validation annotations
  • Hardcode configuration
建议:
  • 使用构造函数注入
  • 使用Spring Data仓库
  • 实现完善的错误处理
  • 为不同环境使用配置文件
不建议:
  • 使用字段注入(在字段上添加@Autowired)
  • 直接暴露实体类
  • 跳过验证注解
  • 硬编码配置

Troubleshooting

问题排查

IssueCauseSolution
Bean not foundMissing @ComponentAdd stereotype annotation
Circular dependencyConstructor circularUse setter or @Lazy
N+1 queriesMissing fetch joinUse @EntityGraph or JOIN FETCH
问题原因解决方案
Bean未找到缺少@Component注解添加 stereotype 注解
循环依赖构造函数循环依赖使用setter注入或@Lazy注解
N+1查询问题缺少fetch join使用@EntityGraph或JOIN FETCH

References

参考资料