Spring is the dominant framework in professional Java web development. Its core idea is Dependency Injection - instead of a class creating the objects it depends on, those dependencies are handed to it from the outside, which makes code far easier to test and reconfigure.
The problem Spring solves
// Without DI - tightly coupled, hard to test
public class OrderService {
private EmailSender emailSender = new EmailSender(); // hardcoded dependency
}
// With DI - the dependency is handed in, not created internally
public class OrderService {
private final EmailSender emailSender;
public OrderService(EmailSender emailSender) {
this.emailSender = emailSender;
}
}
With the second version, tests can hand in a fake EmailSender instead of a real one - no actual emails get sent during a test run.
Spring Boot: a REST controller
Spring Boot builds on core Spring to make building web APIs fast, using annotations instead of the manual servlet wiring from the previous lesson:
@RestController
@RequestMapping("/api/students")
public class StudentController {
private final StudentRepository repository;
public StudentController(StudentRepository repository) {
this.repository = repository; // Spring injects this automatically
}
@GetMapping("/{id}")
public Student getStudent(@PathVariable int id) {
return repository.findById(id);
}
@PostMapping
public Student createStudent(@RequestBody Student student) {
return repository.save(student);
}
}
What Spring is doing for you
@RestController tells Spring this class handles web requests and returns data (usually JSON) directly. @GetMapping/@PostMapping map HTTP methods and URL paths to specific methods. Spring automatically creates a StudentController, sees it needs a StudentRepository in its constructor, creates or reuses one, and injects it - all without you writing a single new StudentController(...) anywhere. That automatic wiring is Dependency Injection in practice, and it is the foundation nearly all modern Java web backends are built on.