[!NOTE] Nobody in the modern corporate world builds web endpoints using raw Java Web Sockets or legacy Servlets. They use the Spring Framework—specifically, the Spring Boot extension.
Spring Boot takes the insanely verbose hundreds of XML configuration files required by older Java EE systems, and automates it via "Opinionated Convention over Configuration."
The Inversion of Control (IoC) Container
The core majesty of Spring is something called Dependency Injection.
Normally, if an AuthenticationService needs to talk to a UserRepository, you write:
UserRepository repo = new UserRepository();
This is called "Tight Coupling". It makes unit testing and upgrading impossible.
In Spring, you NEVER type new. Spring creates one giant master Object (a Bean) of every class at startup. When your AuthenticationService needs a repository, you just use the @Autowired annotation, and Spring magically injects the required database connector object into the slot perfectly!
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
// 1. We tell Spring: "You are in control of this class. Track it."
@Service
public class AuthenticationService {
// 2. We ask Spring: "Hey, give me a master SQL connector. I refuse to make it myself!"
@Autowired
private UserRepository repo;
public void login() {
// We use the injected repo flawlessly!
repo.findUserByUsername("admin");
}
}
Building a Lightning Fast REST API
Spring Boot embeds an entire Tomcat Web Server directly inside the Jar file.
You literally write 15 lines of code, click "Run", and you instantly have a production-ready HTTP server listening on Port 8080.
import org.springframework.web.bind.annotation.*;
import java.util.List;
// Signals Spring Boot to spin up routes over the internet
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@Autowired
private UserService service;
// Handles an incoming 'GET https://quizmaker.co.in/api/v1/users' request!
@GetMapping
public List<User> fetchAllUsers() {
// Spring automatically converts this Java ArrayList into a JSON Array payload
// to send to the Firefox/Chrome frontend browser!
return service.getAll();
}
}
[!TIP] If you want to get hired as a Java Backend Engineer, learning Core Java is only 50% of the battle. The other 50% is demonstrating deep fluency in building Spring Boot REST APIs connected to PostgreSQL!
The Usual Spring Boot Layering
A Spring Boot application is easier to maintain when each layer has a clear job. Controllers handle HTTP, services hold business logic, repositories talk to data storage, and models or DTOs carry data.
Typical Flow
HTTP request
-> Controller
-> Service
-> Repository
-> Database
Constructor Injection
@Service
class UserService {
private final UserRepository userRepository;
UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
Constructor injection makes required dependencies clear and improves testability. It is usually preferred over field injection in modern Spring code.
Common Mistakes
- Putting business logic directly inside controllers.
- Using field injection everywhere instead of constructor injection.
- Returning database entities directly from every API without thinking about DTOs.
- Ignoring validation and error response design.
Mini Practice
Sketch a tiny quiz API with QuizController, QuizService, and QuizRepository. Write one method name for each layer and describe what it should do.
Practice Lab: Sketch a Spring Boot API
Design the layers of a small REST feature before writing full framework code.
- Create class names for
QuizController,QuizService, andQuizRepository. - Write one method signature for listing quizzes in each layer.
- Decide what the controller receives and returns.
- Decide what business rule belongs in the service.
- Use constructor injection in the service and controller examples.
Goal: Separate HTTP handling, business logic, and data access responsibilities.
Revision Checkpoint
- Spring Boot: Opinionated way to build Java apps quickly.
- Bean: Object managed by the Spring container.
- Dependency injection: Framework supplies required dependencies.
@RestController: Handles HTTP routes and returns response bodies.- Layering: Controller, service, repository responsibilities should stay separate.
Before the quiz: Explain what logic belongs in controller vs service.