What is Spring Boot?
Spring Boot is an opinionated framework built on top of Spring that lets you create production-ready Java applications with minimal configuration. It auto-configures the Spring ecosystem so you can focus on writing business logic.
Key Features
- Embedded Tomcat / Jetty — no WAR deployment needed
- Auto-configuration — sensible defaults out of the box
- Spring Initializr — generate a project in seconds
- Actuator — health checks, metrics, and monitoring
- Seamless integration — JPA, Security, Kafka, Redis, etc.
Project Setup
The fastest way to start is start.spring.io. Select: Maven, Java, the latest stable Spring Boot, and add dependencies: Spring Web, Spring Data JPA, MySQL Driver.
Maven Dependencies (pom.xml)
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Project Structure
├── main/
│ ├── java/com/example/
│ │ ├── Application.java // @SpringBootApplication
│ │ ├── controller/ // REST controllers
│ │ ├── service/ // Business logic
│ │ ├── repository/ // JPA repositories
│ │ ├── entity/ // JPA entities
│ │ └── dto/ // Data Transfer Objects
│ └── resources/
│ └── application.yml
└── test/
IoC & Dependency Injection
Inversion of Control (IoC) means Spring creates and manages your objects (beans). Dependency Injection (DI) wires dependencies automatically.
public class UserService {
private final UserRepository repo;
// Constructor injection (recommended)
public UserService(UserRepository repo) {
this.repo = repo;
}
}
@Autowired field injection — it makes dependencies explicit and supports immutability.Key Annotations
@SpringBootApplication— entry point; combines @Configuration, @EnableAutoConfiguration, @ComponentScan@RestController— marks a class as a REST controller (response body auto-serialised to JSON)@Service— business logic layer bean@Repository— data access layer bean; enables exception translation@Component— generic Spring-managed bean@Autowired— injects a bean (prefer constructor injection)@Value("${prop}")— injects a property value@Transactional— wraps a method in a database transaction
application.yml / properties
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
jpa:
hibernate:
ddl-auto: update
show-sql: true
app:
owner-email: you@example.com
application-local.yml (gitignored) for local secrets. Spring picks it up with spring.profiles.active=local.@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService service;
public UserController(UserService service) { this.service = service; }
@GetMapping
public List<User> getAll() { return service.findAll(); }
@GetMapping("/{id}")
public User getById(@PathVariable Long id) { return service.findById(id); }
@PostMapping
public ResponseEntity<User> create(@RequestBody @Valid UserDto dto) {
return ResponseEntity.status(201).body(service.create(dto));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
service.delete(id); return ResponseEntity.noContent().build();
}
}
Request Mapping
@GetMapping— read resource(s)@PostMapping— create resource@PutMapping— replace resource@PatchMapping— partial update@DeleteMapping— delete resource@PathVariable— extract from URL path (/users/{id})@RequestParam— extract query parameter (?page=1)@RequestBody— deserialise JSON body to object
Validation
Add spring-boot-starter-validation and annotate your DTO fields.
@NotBlank(message = "Name is required")
private String name;
@Email(message = "Invalid email")
private String email;
@Min(value = 18, message = "Must be 18+")
private int age;
}
Use @Valid on the controller @RequestBody parameter to trigger validation.
Exception Handling
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
ResponseEntity<String> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(404).body(ex.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
ResponseEntity<Map<String,String>> handleValidation(MethodArgumentNotValidException ex) {
Map<String,String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(e -> errors.put(e.getField(), e.getDefaultMessage()));
return ResponseEntity.badRequest().body(errors);
}
}
Spring Data JPA
Spring Data JPA abstracts the persistence layer. You define repository interfaces and Spring generates the SQL at runtime.
- Add
spring-boot-starter-data-jpa+ your DB driver - Configure
spring.datasourceinapplication.yml - Annotate your entity with
@Entity - Extend
JpaRepository<Entity, IdType>
Entities & Repositories
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(unique = true, nullable = false)
private String email;
}
public interface UserRepository extends JpaRepository<User, Long> { }
Query Methods
// Derived query — Spring generates SQL automatically
Optional<User> findByEmail(String email);
List<User> findByNameContainingIgnoreCase(String name);
// Custom JPQL
@Query("SELECT u FROM User u WHERE u.age > :age")
List<User> findUsersOlderThan(@Param("age") int age);
}
Spring Security Basics
Add spring-boot-starter-security. By default it secures all endpoints with HTTP Basic auth and a random password printed in the console.
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults())
.build();
}
}
Build & Deploy
Build a JAR
java -jar target/app-0.0.1-SNAPSHOT.jar
Docker
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
docker run -p 8080:8080 my-app
SPRING_PROFILES_ACTIVE=prod as an env var to activate production config without rebuilding the JAR.