iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Spring Boot Intro

Spring Boot: opinionated Java framework for production apps. Auto-configuration, starters, embedded server.

Java — Spring Boot

EXAMPLE
// ===== Why Spring Boot =====
// - Convention over configuration (boring is good)
// - Embedded Tomcat / Jetty / Undertow (no app server install)
// - Massive ecosystem (Security, Data JPA, WebFlux, Cloud)
// - Production features (actuator, metrics, health)
// - First-class testing support

// ===== Create a project =====
// https://start.spring.io
// or:
spring init --build maven --dependencies web,data-jpa,postgresql,actuator myapp

// ===== Main class =====
@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

// ===== A REST controller =====
@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService users;
    public UserController(UserService users) { this.users = users; }   // constructor injection

    @GetMapping("/{id}")
    public User get(@PathVariable Long id) {
        return users.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User create(@Valid @RequestBody CreateUserDto dto) {
        return users.create(dto);
    }
}

// ===== Service =====
@Service
public class UserService {
    private final UserRepository repo;
    public UserService(UserRepository repo) { this.repo = repo; }

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

    @Transactional
    public User create(CreateUserDto dto) {
        var user = new User(dto.email(), dto.name());
        return repo.save(user);
    }
}

// ===== Repository (Spring Data JPA) =====
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
    List<User> findByCreatedAtAfter(Instant cutoff);
}

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

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

    private String name;

    @CreationTimestamp
    private Instant createdAt;

    protected User() {}
    public User(String email, String name) {
        this.email = email;
        this.name = name;
    }
    // getters
}

// ===== application.yml =====
spring:
  application:
    name: shop-api
  datasource:
    url: jdbc:postgresql://localhost:5432/shop
    username: dev
    password: dev
  jpa:
    hibernate:
      ddl-auto: validate     // never 'update' or 'create' in production
    show-sql: false
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus

// ===== Validation =====
public record CreateUserDto(
    @Email String email,
    @NotBlank @Size(max = 100) String name
) {}

// ===== Exception handling =====
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleValidation(MethodArgumentNotValidException ex) {
        return ResponseEntity.badRequest().body(Map.of("error", ex.getMessage()));
    }
}

// ===== Tests =====
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
    @Autowired MockMvc mvc;

    @Test
    void getsUser() throws Exception {
        mvc.perform(get("/api/users/1"))
           .andExpect(status().isOk())
           .andExpect(jsonPath("$.email").value("a@x.io"));
    }
}

// ===== Patterns =====
// - Constructor injection (no @Autowired needed since 4.3)
// - Spring Data JPA for boring CRUD
// - @Transactional on write paths
// - Validation via bean validation
// - Actuator + Micrometer + Prometheus for metrics

// ===== Pitfalls =====
// - ddl-auto: update in production
// - Field injection (use constructor)
// - N+1 queries (use @EntityGraph or fetch joins)
// - Catching Exception broadly in @ControllerAdvice

Why it matters

Spring Boot: opinionated, productive, batteries included. Controller + Service + Repository + Entity covers most CRUD. application.yml configures everything; Actuator + Prometheus expose metrics. Master DI + JPA + validation + tests and you can ship serious Java services.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
@RestController
class HiController {
    @GetMapping("/hi")
    String hi() { return "hello"; }
}
Try it Yourself »

Discussion

Loading…