0% found this document useful (0 votes)
3 views52 pages

Java SpringBoot Backend Notes PlutoAcademy

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views52 pages

Java SpringBoot Backend Notes PlutoAcademy

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Spring Boot

Java Backend Development — Complete Notes

IoC • REST APIs • JPA • Security • Microservices

From Setup to Production — Beginner to Job-Ready

Spring Boot 3.x • Java 17+

Java Backend with

Spring Boot
Comprehensive Study Notes for Students & Developers

Spring Core REST API Spring Data JPA Spring Security Maven/Gradle Microservices Docker

Pluto Academy

[Link] • @[Link] • MERN Stack & Java Backend Courses


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

■ Table of Contents

1. Introduction to Spring & Spring Boot


2. Project Setup — Spring Initializr & Project Structure
3. Dependency Injection & IoC Container
4. Spring Beans — Lifecycle, Scopes & Annotations
5. Building REST APIs with Spring MVC
6. Request Handling — Path Variables, Query Params, Request Body
7. Spring Data JPA & Hibernate
8. Database Configuration & Relationships
9. Exception Handling in Spring Boot
10. Spring Boot Validation
11. Spring Security — Authentication & Authorization
12. JWT — JSON Web Token Authentication
13. Spring Boot Testing
14. Spring Boot Actuator & Monitoring
15. Configuration — [Link] / YAML / Profiles
16. Spring Boot with Lombok
17. Pagination & Sorting
18. File Upload & Download
19. Spring Boot Scheduling & Async
20. Microservices with Spring Boot
21. Docker & Deployment
22. Key Annotations Cheat Sheet

Page 2 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

1. Introduction to Spring & Spring Boot

The Spring Framework is a comprehensive, lightweight Java framework for building enterprise applications. It
solves common problems like object creation, dependency management, database access, and web
development through a consistent, non-invasive programming model.

Spring Framework Spring Boot

Full enterprise framework. Requires extensive XML or Opinionated wrapper over Spring. Auto-configures
annotation configuration. Manual setup of every everything based on classpath. Embedded server
component (DataSource, Dispatcher Servlet, etc.). (Tomcat) — no WAR deployment needed.
Maximum control, maximum boilerplate. Production-ready in minutes.

What Spring Boot Gives You Out of the Box

Feature Description

Auto-Configuration Detects JARs on classpath and configures beans automatically

Embedded Server Tomcat / Jetty / Undertow embedded — just run the JAR

Starter
spring-boot-starter-web pulls Spring MVC + Jackson + Tomcat
Dependencies

Spring Initializr [Link] — generate project in seconds

Actuator Production metrics, health checks, info endpoints built-in

DevTools Hot reload during development

Externalized
[Link] / .yml / environment variables / profiles
Config

Spring Ecosystem Overview

Module Purpose

Spring Core IoC container, Dependency Injection — the heart of everything

Spring MVC Model-View-Controller web framework for REST & web apps

Spring Data JPA Abstraction over JPA/Hibernate — repositories & query methods

Spring Security Authentication, Authorization, OAuth2, JWT

Spring Cloud Microservices tools — service discovery, config server, gateway

Spring Batch Batch processing — read/process/write large data volumes

Spring WebFlux Reactive, non-blocking web framework (alternative to Spring MVC)

Spring AMQP Messaging with RabbitMQ

Spring Kafka Messaging with Apache Kafka

Page 3 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

2. Project Setup — Spring Initializr & Project Structure

Creating a Spring Boot Project

Spring Initializr ([Link]) is the fastest way to bootstrap a project. Select: Project (Maven/Gradle),
Language (Java), Spring Boot version, Group/Artifact, Java version, and Dependencies.

# Popular starter dependencies to add:

Spring Web → spring-boot-starter-web (REST APIs)

Spring Data JPA → spring-boot-starter-data-jpa

H2 Database → com.h2database:h2 (in-memory dev DB)

MySQL Driver → mysql:mysql-connector-java

Spring Security → spring-boot-starter-security

Spring Boot DevTools → spring-boot-devtools (hot reload)

Lombok → [Link]:lombok

Spring Boot Actuator → spring-boot-starter-actuator

Validation → spring-boot-starter-validation

Standard Project Structure (Maven)

my-app/

■■■ src/

■ ■■■ main/

■ ■ ■■■ java/com/example/myapp/

■ ■ ■ ■■■ [Link] ← @SpringBootApplication (entry point)

■ ■ ■ ■■■ controller/

■ ■ ■ ■ ■■■ [Link] ← REST endpoints (@RestController)

■ ■ ■ ■■■ service/

■ ■ ■ ■ ■■■ [Link] ← Interface

■ ■ ■ ■ ■■■ [Link] ← @Service implementation

■ ■ ■ ■■■ repository/

■ ■ ■ ■ ■■■ [Link] ← @Repository / JpaRepository

■ ■ ■ ■■■ model/ (or entity/)

■ ■ ■ ■ ■■■ [Link] ← @Entity (JPA / Hibernate)

Page 4 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

■ ■ ■ ■■■ dto/

■ ■ ■ ■ ■■■ [Link] ← Data Transfer Object

■ ■ ■ ■■■ exception/

■ ■ ■ ■ ■■■ [Link]

■ ■ ■ ■■■ config/

■ ■ ■ ■ ■■■ [Link]

■ ■ ■ ■■■ util/

■ ■ ■■■ resources/

■ ■ ■■■ [Link] ← or [Link]

■ ■ ■■■ [Link]

■ ■ ■■■ static/ templates/

■ ■■■ test/

■ ■■■ java/com/example/myapp/

■ ■■■ [Link]

■■■ [Link] ← Maven build file

■■■ Dockerfile

// [Link] — Main entry point

@SpringBootApplication

// = @Configuration + @EnableAutoConfiguration + @ComponentScan

public class MyAppApplication {

public static void main(String[] args) {

[Link]([Link], args);

■ Follow the layered architecture strictly: Controller → Service → Repository → Database. Never let Controller talk
directly to Repository.

Page 5 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

3. Dependency Injection & IoC Container

Inversion of Control (IoC): Instead of your code creating its own dependencies, the Spring IoC container
creates and manages objects for you. You declare what you need — Spring provides it. Dependency Injection
(DI) is Spring's mechanism for implementing IoC.

Three Types of Dependency Injection

// ■ WITHOUT Spring — you manually create objects (tight coupling)

class OrderService {

private PaymentService paymentService = new PaymentService(); // bad

// ■■ 1. CONSTRUCTOR INJECTION ■ (RECOMMENDED — mandatory deps)

@Service

public class OrderService {

private final PaymentService paymentService; // final = immutable

private final EmailService emailService;

// Spring injects via constructor automatically

public OrderService(PaymentService paymentService, EmailService emailService) {

[Link] = paymentService;

[Link] = emailService;

// ■■ 2. SETTER INJECTION (optional dependencies)

@Service

public class ReportService {

private CacheService cacheService;

@Autowired

public void setCacheService(CacheService cacheService) {

[Link] = cacheService;

Page 6 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

// ■■ 3. FIELD INJECTION (convenient but avoid in production)

@Service

public class ProductService {

@Autowired // Spring injects directly into the field

private ProductRepository productRepository;

Why Constructor Injection is Best

Aspect Constructor Injection ■ Field Injection ■

Immutability Fields can be final Cannot be final

Testing Easy — pass mocks via constructor Needs reflection / @InjectMocks

Circular
Detected at startup (fail-fast) Detected only at runtime
dependency

Null safety Guaranteed not null Can be null if Spring fails

Lombok @RequiredAr
Works perfectly Not applicable
gsConstructor

■ With Lombok @RequiredArgsConstructor, you don't even need to write the constructor! Spring detects the single
constructor and injects automatically.

Page 7 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

4. Spring Beans — Lifecycle, Scopes & Annotations

A Spring Bean is any object that is managed by the Spring IoC container. Spring creates, wires, manages, and
destroys beans based on configuration.

Bean Scopes

Scope Description Default?

singleton One instance per Spring container — shared everywhere. Default scope. ■ Yes

prototype New instance created every time the bean is requested. No

request One instance per HTTP request. Web applications only. No

session One instance per HTTP session. Web applications only. No

application One instance per ServletContext (entire app lifecycle). No

websocket One instance per WebSocket session. No

// Singleton (default) — most common

@Service // @Service is @Component with semantic meaning

public class UserService { } // → singleton by default

// Explicit scope

@Component

@Scope("prototype") // or ConfigurableBeanFactory.SCOPE_PROTOTYPE

public class ShoppingCart { }

// Declaring beans in @Configuration class

@Configuration

public class AppConfig {

@Bean // method name = bean name by default

public PasswordEncoder passwordEncoder() {

return new BCryptPasswordEncoder();

@Bean

@Primary // preferred when multiple beans of same type exist

public DataSource primaryDataSource() { ... }

Page 8 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

@Bean

@Qualifier("backupDS")

public DataSource backupDataSource() { ... }

// Bean lifecycle hooks

@Component

public class DatabaseInitializer {

@PostConstruct // called after bean is created and wired

public void init() {

[Link]("Bean initialized — run startup logic here");

@PreDestroy // called before bean is destroyed

public void cleanup() {

[Link]("Bean destroyed — close connections here");

Page 9 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

5. Building REST APIs with Spring MVC

Spring MVC is the web framework inside Spring Boot. @RestController = @Controller + @ResponseBody. It
automatically serializes Java objects to JSON (via Jackson) and back.

HTTP Methods → CRUD Mapping

HTTP
Annotation Purpose Success Status
Method

GET @GetMapping Retrieve resource(s) 200 OK

POST @PostMapping Create new resource 201 Created

PUT @PutMapping Replace entire resource 200 OK

PATCH @PatchMapping Partial update 200 OK

DELETE @DeleteMapping Remove resource 204 No Content

Full CRUD Controller — User Management API

@RestController

@RequestMapping("/api/v1/users")

public class UserController {

private final UserService userService;

// Constructor injection (Lombok @RequiredArgsConstructor replaces this)

public UserController(UserService userService) {

[Link] = userService;

// GET all users

@GetMapping

public ResponseEntity> getAllUsers() {

return [Link]([Link]());

// GET single user

@GetMapping("/{id}")

public ResponseEntity getUserById(@PathVariable Long id) {

Page 10 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

return [Link]([Link](id));

// POST — create user

@PostMapping

public ResponseEntity createUser(@Valid @RequestBody CreateUserRequest req) {

UserDTO created = [Link](req);

URI location = [Link]("/api/v1/users/" + [Link]());

return [Link](location).body(created);

// PUT — update user

@PutMapping("/{id}")

public ResponseEntity updateUser(

@PathVariable Long id,

@Valid @RequestBody UpdateUserRequest req) {

return [Link]([Link](id, req));

// DELETE user

@DeleteMapping("/{id}")

public ResponseEntity deleteUser(@PathVariable Long id) {

[Link](id);

return [Link]().build();

// GET with query parameters

@GetMapping("/search")

public ResponseEntity> searchUsers(

@RequestParam(defaultValue = "") String name,

@RequestParam(defaultValue = "0") int page,

@RequestParam(defaultValue = "10") int size) {

Page 11 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

return [Link]([Link](name, page, size));

Page 12 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

6. Request Handling — Parameters, Body & Response

Extracting Data from Requests

// @PathVariable — from URL path: /users/42

@GetMapping("/users/{id}")

public User getUser(@PathVariable Long id) { ... }

// Multiple path variables: /orders/5/items/3

@GetMapping("/orders/{orderId}/items/{itemId}")

public Item getItem(@PathVariable Long orderId, @PathVariable Long itemId) { ... }

// @RequestParam — from query string: /users?name=Alice&active;=true

@GetMapping("/users")

public List search(

@RequestParam String name,

@RequestParam(required = false) Boolean active,

@RequestParam(defaultValue = "0") int page) { ... }

// @RequestBody — JSON body → Java object

@PostMapping("/users")

public User create(@RequestBody CreateUserRequest request) { ... }

// @RequestHeader — read HTTP headers

@GetMapping("/profile")

public User profile(@RequestHeader("Authorization") String token) { ... }

// @CookieValue — read cookies

@GetMapping("/session")

public String session(@CookieValue("SESSION_ID") String sessionId) { ... }

// HttpServletRequest — raw access to request

@GetMapping("/info")

public String info(HttpServletRequest request) {

Page 13 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

return [Link](); // client IP

ResponseEntity — Full Control Over HTTP Response

// Custom status + body + headers

return ResponseEntity

.status([Link]) // 201

.header("X-Custom-Header", "value")

.body(user);

// Common shortcuts

[Link](body) // 200 + body

[Link](locationUri).body(body) // 201 + Location header

[Link]().build() // 204 empty

[Link]().build() // 404 empty

[Link]().body(errorMsg) // 400 + body

// Generic type for cleaner code

public ResponseEntity> getUser(@PathVariable Long id) {

UserDTO user = [Link](id);

return [Link]([Link](user));

// Standard API Response wrapper (good practice)

public class ApiResponse {

private boolean success;

private String message;

private T data;

private LocalDateTime timestamp;

public static ApiResponse success(T data) {

return new ApiResponse<>(true, "Success", data, [Link]());

Page 14 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

Page 15 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

7. Spring Data JPA & Hibernate

JPA (Java Persistence API) is the standard specification for ORM in Java. Hibernate is the most popular JPA
implementation. Spring Data JPA wraps Hibernate and provides repositories — eliminating boilerplate CRUD
code entirely.

Entity Class — Mapping Java to Database

@Entity

@Table(name = "users",

uniqueConstraints = @UniqueConstraint(columnNames = "email"))

@Data // Lombok: getters, setters, equals, hashCode, toString

@NoArgsConstructor // Lombok: required by JPA

@AllArgsConstructor // Lombok

@Builder // Lombok: builder pattern

public class User {

@Id

@GeneratedValue(strategy = [Link])

private Long id;

@Column(nullable = false, length = 100)

private String name;

@Column(nullable = false, unique = true)

private String email;

@Column(nullable = false)

private String password;

@Enumerated([Link]) // store as 'ADMIN' not 0

@Column(nullable = false)

private Role role = [Link];

@Column(nullable = false, updatable = false)

@CreationTimestamp // Hibernate: auto-set on insert

Page 16 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

private LocalDateTime createdAt;

@UpdateTimestamp // Hibernate: auto-update on update

private LocalDateTime updatedAt;

@Column(name = "is_active", nullable = false)

private boolean active = true;

enum Role { USER, ADMIN, MODERATOR }

JpaRepository — Zero Boilerplate CRUD

@Repository

public interface UserRepository extends JpaRepository {

// JpaRepository gives you for FREE:

// save(entity), saveAll(), findById(id), findAll(), deleteById(id),

// delete(entity), count(), existsById(id) and more

// ■■ Derived Query Methods (no SQL needed — Spring generates queries)

Optional findByEmail(String email);

List findByActiveTrue();

List findByNameContainingIgnoreCase(String name);

List findByRoleOrderByNameAsc(Role role);

boolean existsByEmail(String email);

long countByRole(Role role);

void deleteByEmail(String email);

// ■■ Custom JPQL query

@Query("SELECT u FROM User u WHERE [Link] = :email AND [Link] = true")

Optional findActiveByEmail(@Param("email") String email);

// ■■ Native SQL query

@Query(value = "SELECT * FROM users WHERE created_at > :date",

Page 17 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

nativeQuery = true)

List findUsersCreatedAfter(@Param("date") LocalDateTime date);

// ■■ Modifying query (UPDATE/DELETE)

@Modifying

@Transactional

@Query("UPDATE User u SET [Link] = false WHERE [Link] = :id")

int deactivateUser(@Param("id") Long id);

// ■■ Pagination

Page findByRole(Role role, Pageable pageable);

Service Layer — Transactional Business Logic

@Service

@Transactional // all methods in this class are transactional by default

@RequiredArgsConstructor // Lombok — generates constructor for final fields

public class UserServiceImpl implements UserService {

private final UserRepository userRepository;

private final PasswordEncoder passwordEncoder;

@Override

@Transactional(readOnly = true) // optimization: no write lock

public List findAll() {

return [Link]()

.stream()

.map(this::toDTO)

.collect([Link]());

@Override

@Transactional(readOnly = true)

Page 18 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

public UserDTO findById(Long id) {

return [Link](id)

.map(this::toDTO)

.orElseThrow(() -> new ResourceNotFoundException("User", id));

@Override

public UserDTO create(CreateUserRequest req) {

if ([Link]([Link]()))

throw new DuplicateEmailException([Link]());

User user = [Link]()

.name([Link]())

.email([Link]())

.password([Link]([Link]()))

.role([Link])

.build();

return toDTO([Link](user));

private UserDTO toDTO(User user) {

return new UserDTO([Link](), [Link](), [Link](), [Link]());

Page 19 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

8. Database Configuration & JPA Relationships

[Link] — Database Config

# ■■ MySQL Configuration

[Link]=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone;=UTC

[Link]=root

[Link]=secret

[Link]-class-name=[Link]

# ■■ JPA / Hibernate

[Link]-auto=update

# Options: none | validate | update | create | create-drop

# update — safe for dev (adds columns, doesn't drop)

# create-drop — drops and recreates on start/stop (use for tests)

# validate — production: verify schema matches entities

[Link]-sql=true # log SQL statements

[Link].format_sql=true

[Link]=[Link].MySQL8Dialect

# ■■ Connection Pool (HikariCP — default in Spring Boot)

[Link]-pool-size=10

[Link]-idle=2

[Link]-timeout=20000

# ■■ H2 In-Memory (for development / tests)

[Link]=jdbc:h2:mem:testdb

[Link]-class-name=[Link]

[Link]=true # access at /h2-console

JPA Relationships

// ■■ @OneToMany / @ManyToOne (Most Common)

Page 20 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

// One Department → Many Employees

@Entity

public class Department {

@Id @GeneratedValue(strategy = [Link])

private Long id;

private String name;

@OneToMany(mappedBy = "department", cascade = [Link], fetch = [Link])

@JsonManagedReference // prevents infinite recursion in JSON

private List employees = new ArrayList<>();

@Entity

public class Employee {

@Id @GeneratedValue(strategy = [Link])

private Long id;

private String name;

@ManyToOne(fetch = [Link])

@JoinColumn(name = "department_id") // FK column in employees table

@JsonBackReference

private Department department;

// ■■ @ManyToMany

@Entity

public class Student {

@ManyToMany(cascade = {[Link], [Link]})

@JoinTable(name = "student_course",

joinColumns = @JoinColumn(name = "student_id"),

inverseJoinColumns = @JoinColumn(name = "course_id"))

private Set courses = new HashSet<>();

Page 21 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

// ■■ @OneToOne

@Entity

public class User {

@OneToOne(cascade = [Link])

@JoinColumn(name = "profile_id", referencedColumnName = "id")

private UserProfile profile;

Annotation DB Relationship Example

@OneToOne One row ↔ One row User ↔ UserProfile

@OneToMany One row ↔ Many rows Department → Employees

@ManyToOne Many rows → One row Employee → Department (FK side)

Many rows ↔ Many rows


@ManyToMany Student ↔ Course
(join table)

■■ Always use [Link] for @OneToMany and @ManyToMany to avoid loading entire graphs. Use JOIN
FETCH in JPQL when you need the data.

Page 22 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

9. Exception Handling in Spring Boot

// ■■ Custom exception classes

public class ResourceNotFoundException extends RuntimeException {

public ResourceNotFoundException(String resource, Object id) {

super(resource + " not found with id: " + id);

public class DuplicateEmailException extends RuntimeException {

public DuplicateEmailException(String email) {

super("Email already in use: " + email);

// ■■ Error Response DTO

@Data @AllArgsConstructor

public class ErrorResponse {

private int status;

private String error;

private String message;

private LocalDateTime timestamp;

private String path;

// ■■ Global Exception Handler

@RestControllerAdvice // = @ControllerAdvice + @ResponseBody

public class GlobalExceptionHandler {

@ExceptionHandler([Link])

public ResponseEntity handleNotFound(

ResourceNotFoundException ex, HttpServletRequest request) {

Page 23 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

ErrorResponse err = new ErrorResponse(

404, "Not Found", [Link](),

[Link](), [Link]());

return [Link](HttpStatus.NOT_FOUND).body(err);

@ExceptionHandler([Link])

public ResponseEntity> handleValidation(

MethodArgumentNotValidException ex) {

Map errors = new HashMap<>();

[Link]().getFieldErrors()

.forEach(e -> [Link]([Link](), [Link]()));

return [Link]().body(errors);

@ExceptionHandler([Link])

public ResponseEntity handleDuplicate(

DuplicateEmailException ex, HttpServletRequest request) {

ErrorResponse err = new ErrorResponse(

409, "Conflict", [Link](),

[Link](), [Link]());

return [Link]([Link]).body(err);

@ExceptionHandler([Link]) // catch-all

public ResponseEntity handleGeneral(

Exception ex, HttpServletRequest request) {

ErrorResponse err = new ErrorResponse(

500, "Internal Server Error", "An unexpected error occurred",

[Link](), [Link]());

return [Link]().body(err);

Page 24 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

Page 25 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

10. Spring Boot Validation

// Dependency: spring-boot-starter-validation

// ■■ Request DTO with validation annotations

public class CreateUserRequest {

@NotBlank(message = "Name is required")

@Size(min = 2, max = 100, message = "Name must be 2-100 chars")

private String name;

@NotBlank(message = "Email is required")

@Email(message = "Invalid email format")

private String email;

@NotBlank(message = "Password is required")

@Size(min = 8, message = "Password must be at least 8 characters")

@Pattern(regexp = "^(?=.*[A-Z])(?=.*[0-9]).+$",

message = "Password must contain uppercase letter and digit")

private String password;

@NotNull(message = "Age is required")

@Min(value = 18, message = "Must be at least 18")

@Max(value = 120, message = "Invalid age")

private Integer age;

@NotNull

@Future(message = "Expiry date must be in the future")

private LocalDate expiryDate;

// ■■ Trigger validation with @Valid on controller parameter

@PostMapping

public ResponseEntity create(@Valid @RequestBody CreateUserRequest req) {

Page 26 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

return [Link](uri).body([Link](req));

Annotation Purpose

@NotNull Field must not be null

@NotBlank String must not be null or empty/whitespace

@NotEmpty Collection/String must not be empty (null allowed)

@Size(min,max) String/Collection length between min and max

@Min(value) / @Max(value) Numeric value constraints

@Email Valid email format

@Pattern(regexp) Must match regular expression

@Positive / @Negative Number must be positive/negative

@Past / @Future Date must be in past/future

@DecimalMin / @DecimalMax Decimal number range

@Valid Trigger cascade validation on nested objects

Page 27 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

11. Spring Security — Authentication & Authorization

Spring Security provides comprehensive authentication and authorization support. It works as a chain of filters
intercepting every HTTP request before it reaches your controllers.

Security Configuration (Spring Boot 3.x / Spring Security 6+)

@Configuration

@EnableWebSecurity

@EnableMethodSecurity // enables @PreAuthorize, @PostAuthorize

@RequiredArgsConstructor

public class SecurityConfig {

private final JwtAuthenticationFilter jwtFilter;

private final UserDetailsService userDetailsService;

@Bean

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

return http

.csrf(csrf -> [Link]()) // disable CSRF for REST APIs

.sessionManagement(session ->

[Link]([Link]))

.authorizeHttpRequests(auth -> auth

.requestMatchers("/api/auth/**").permitAll() // public

.requestMatchers("/api/admin/**").hasRole("ADMIN")

.requestMatchers([Link], "/api/products/**").permitAll()

.anyRequest().authenticated() // everything else: auth

.addFilterBefore(jwtFilter, [Link])

.build();

@Bean

public PasswordEncoder passwordEncoder() {

Page 28 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

return new BCryptPasswordEncoder(12); // strength 12 (default 10)

@Bean

public AuthenticationManager authenticationManager(

AuthenticationConfiguration config) throws Exception {

return [Link]();

// UserDetailsService — load user from DB for authentication

@Service

@RequiredArgsConstructor

public class UserDetailsServiceImpl implements UserDetailsService {

private final UserRepository userRepository;

@Override

public UserDetails loadUserByUsername(String email) {

return [Link](email)

.orElseThrow(() -> new UsernameNotFoundException("User not found: " + email));

// User entity must implement UserDetails, or wrap it:

// return new [Link](

// [Link](), [Link](),

// [Link](new SimpleGrantedAuthority("ROLE_" + [Link]())));

Method-Level Security

@RestController

@RequestMapping("/api/users")

public class UserController {

Page 29 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

@GetMapping

@PreAuthorize("hasRole('ADMIN')") // only ADMIN can call this

public List getAll() { ... }

@GetMapping("/me")

@PreAuthorize("isAuthenticated()")

public UserDTO getMyProfile(Authentication auth) {

return [Link]([Link]());

@DeleteMapping("/{id}")

@PreAuthorize("hasRole('ADMIN') or #id == [Link]")

public ResponseEntity delete(@PathVariable Long id) { ... }

Page 30 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

12. JWT — JSON Web Token Authentication

JWT is a compact, self-contained token for securely transmitting information between parties. Structure:
[Link] (Base64 encoded, dot-separated).

JWT Flow — Login → Token → API Access

2. Server Creates 3. Client Stores 5. Server Validates


1. Login 4. API Request
JWT Token JWT

Verifies signature &


POST /api/auth/login Signs token with secret localStorage or Header: Authorization:
expiry, lets request
{email, password} key, returns JWT sessionStorage or cookie Bearer
through

JWT Utility Class & Filter

// Dependency: [Link]:jjwt-api, jjwt-impl, jjwt-jackson

@Component

public class JwtUtil {

@Value("${[Link]}")

private String secretKey;

@Value("${[Link]}") // default: 24 hours in ms

private long jwtExpiration;

private SecretKey getSigningKey() {

return [Link]([Link](secretKey));

public String generateToken(UserDetails userDetails) {

return [Link]()

.subject([Link]())

.issuedAt(new Date())

.expiration(new Date([Link]() + jwtExpiration))

.claim("role", [Link]())

.signWith(getSigningKey())

.compact();

Page 31 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

public String extractUsername(String token) {

return [Link]().verifyWith(getSigningKey()).build()

.parseSignedClaims(token).getPayload().getSubject();

public boolean isTokenValid(String token, UserDetails userDetails) {

final String username = extractUsername(token);

return [Link]([Link]()) && !isExpired(token);

private boolean isExpired(String token) {

return [Link]().verifyWith(getSigningKey()).build()

.parseSignedClaims(token).getPayload()

.getExpiration().before(new Date());

// JWT Filter — runs on every request

@Component @RequiredArgsConstructor

public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final JwtUtil jwtUtil;

private final UserDetailsService userDetailsService;

@Override

protected void doFilterInternal(HttpServletRequest req,

HttpServletResponse res, FilterChain chain) throws ServletException, IOException {

String authHeader = [Link]("Authorization");

if (authHeader == null || ![Link]("Bearer ")) {

[Link](req, res); return;

Page 32 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

String token = [Link](7);

String email = [Link](token);

if (email != null && [Link]().getAuthentication() == null) {

UserDetails userDetails = [Link](email);

if ([Link](token, userDetails)) {

UsernamePasswordAuthenticationToken authToken =

new UsernamePasswordAuthenticationToken(

userDetails, null, [Link]());

[Link](new WebAuthenticationDetailsSource().buildDetails(req));

[Link]().setAuthentication(authToken);

[Link](req, res);

Page 33 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

13. Spring Boot Testing

Test Type Annotation Loads Best For

@ExtendWith([Link]
Unit Test Nothing Service/Util logic in isolation
s)

Slice Test @WebMvcTest([Link]) Web layer only Controller + validation

Slice Test @DataJpaTest JPA layer + H2 Repository queries

Integration @SpringBootTest Full app context End-to-end flow

// ■■ Unit Test — Service with Mockito

@ExtendWith([Link])

class UserServiceTest {

@Mock private UserRepository userRepository;

@Mock private PasswordEncoder passwordEncoder;

@InjectMocks private UserServiceImpl userService;

@Test

void findById_existingUser_returnsDTO() {

// Arrange

User user = [Link]().id(1L).name("Alice").email("a@[Link]").build();

when([Link](1L)).thenReturn([Link](user));

// Act

UserDTO result = [Link](1L);

// Assert

assertThat([Link]()).isEqualTo("Alice");

verify(userRepository, times(1)).findById(1L);

@Test

void findById_nonExistingUser_throwsException() {

when([Link](99L)).thenReturn([Link]());

Page 34 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

assertThatThrownBy(() -> [Link](99L))

.isInstanceOf([Link]);

// ■■ Controller Slice Test with MockMvc

@WebMvcTest([Link])

class UserControllerTest {

@Autowired private MockMvc mockMvc;

@MockBean private UserService userService;

@Autowired private ObjectMapper objectMapper;

@Test

void getUser_returnsUser() throws Exception {

UserDTO dto = new UserDTO(1L, "Alice", "a@[Link]", [Link]);

when([Link](1L)).thenReturn(dto);

[Link](get("/api/v1/users/1")

.contentType(MediaType.APPLICATION_JSON))

.andExpect(status().isOk())

.andExpect(jsonPath("$.name").value("Alice"))

.andExpect(jsonPath("$.email").value("a@[Link]"));

@Test

void createUser_invalidRequest_returns400() throws Exception {

CreateUserRequest req = new CreateUserRequest("", "bad-email", "weak", 15);

[Link](post("/api/v1/users")

.contentType(MediaType.APPLICATION_JSON)

.content([Link](req)))

.andExpect(status().isBadRequest());

Page 35 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

Page 36 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

14. Spring Boot Actuator & Monitoring

# [Link]

[Link]=health,info,metrics,env,beans

[Link]-details=always

[Link]=true

[Link]=My Spring App

[Link]=1.0.0

[Link]=Backend API

Endpoint URL What It Shows

/health /actuator/health App health, DB status, disk space

/info /actuator/info App info (version, description)

/metrics /actuator/metrics JVM memory, HTTP requests, threads

/env /actuator/env All environment properties

/beans /actuator/beans All Spring beans registered

/mappings /actuator/mappings All URL → handler mappings

/loggers /actuator/loggers View/change log levels at runtime

/httptrace /actuator/httptrace Last 100 HTTP request/response traces

Page 37 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

15. Configuration — Properties, YAML & Profiles

# [Link] — YAML format (hierarchical, cleaner)

server:

port: 8080

servlet:

context-path: /api

spring:

application:

name: my-app

datasource:

url: jdbc:mysql://localhost:3306/mydb

username: root

password: ${DB_PASSWORD} # reads from environment variable

jpa:

hibernate:

ddl-auto: update

show-sql: false

jwt:

secret: ${JWT_SECRET}

expiration: 86400000

# ■■ Spring Profiles

# [Link] → activated with [Link]=dev

# [Link] → activated with [Link]=prod

# Activate profile:

# 1. [Link]: [Link]=dev

# 2. JVM arg: -[Link]=prod

# 3. Environment variable: SPRING_PROFILES_ACTIVE=prod

Page 38 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

# ■■ Reading custom properties

@Value("${[Link]}")

private String jwtSecret;

# ■■ Binding a group of properties to a class

@ConfigurationProperties(prefix = "[Link]")

@Data @Component

public class MailProperties {

private String host;

private int port;

private String username;

Page 39 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

16. Spring Boot with Lombok

Annotation Generates

@Getter / @Setter Getter and/or setter methods for all fields

@Data @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor

@NoArgsConstructor No-argument constructor (required by JPA)

@AllArgsConstructor Constructor with all fields

@RequiredArgsConstructor Constructor for all final and @NonNull fields (DI-friendly)

@Builder Builder pattern — [Link]().field(val).build()

@Slf4j private static final Logger log = [Link](...)

@ToString toString() method (exclude = {"password"})

@EqualsAndHashCode equals() and hashCode() based on fields

@Value (Lombok) Immutable class — all fields private final, @Getter, no setters

@NonNull Null check with NullPointerException in constructor/setter

// Before Lombok — 50+ lines of boilerplate

// After Lombok — clean and readable

@Entity

@Data

@NoArgsConstructor

@AllArgsConstructor

@Builder

public class Product {

@Id @GeneratedValue(strategy = [Link])

private Long id;

private String name;

private Double price;

private Integer stock;

// Usage with @Builder:

Product p = [Link]()

Page 40 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

.name("Laptop").price(49999.0).stock(10).build();

// @Slf4j for logging

@Service @Slf4j

public class OrderService {

public void placeOrder(Order order) {

[Link]("Placing order for user: {}", [Link]());

[Link]("Order details: {}", order);

[Link]("Payment failed for order: {}", [Link]());

Page 41 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

17. Pagination & Sorting

// Repository

public interface ProductRepository extends JpaRepository {

Page findByCategory(String category, Pageable pageable);

// Service

public Page getProducts(int page, int size, String sortBy, String dir) {

Sort sort = [Link]("desc")

? [Link](sortBy).descending()

: [Link](sortBy).ascending();

Pageable pageable = [Link](page, size, sort);

return [Link](pageable).map(this::toDTO);

// Controller

@GetMapping

public ResponseEntity> getProducts(

@RequestParam(defaultValue = "0") int page,

@RequestParam(defaultValue = "10") int size,

@RequestParam(defaultValue = "name") String sortBy,

@RequestParam(defaultValue = "asc") String direction) {

return [Link]([Link](page, size, sortBy, direction));

// API call: GET /api/products?page=0&size;=10&sortBy;=price&direction;=desc

// Page response includes:

// content: [...], totalElements: 100, totalPages: 10,

// size: 10, number: 0 (current page), first: true, last: false

Page 42 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

18. File Upload & Download

# [Link]

[Link]-file-size=10MB

[Link]-request-size=10MB

[Link]-dir=./uploads

// File Upload Controller

@RestController

@RequestMapping("/api/files")

@RequiredArgsConstructor

public class FileController {

@Value("${[Link]-dir}")

private String uploadDir;

@PostMapping("/upload")

public ResponseEntity> upload(

@RequestParam("file") MultipartFile file) throws IOException {

if ([Link]()) throw new IllegalArgumentException("File is empty");

String fileName = [Link]() + "_" + [Link]();

Path uploadPath = [Link](uploadDir);

if (![Link](uploadPath)) [Link](uploadPath);

[Link]([Link](), [Link](fileName),

StandardCopyOption.REPLACE_EXISTING);

return [Link]([Link](

"fileName", fileName,

"fileType", [Link](),

"size", [Link]([Link]())));

Page 43 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

@GetMapping("/download/{fileName}")

public ResponseEntity download(@PathVariable String fileName) throws IOException {

Path filePath = [Link](uploadDir).resolve(fileName).normalize();

Resource resource = new UrlResource([Link]());

if (![Link]()) throw new ResourceNotFoundException("File", fileName);

String contentType = [Link](filePath);

return [Link]()

.contentType([Link](contentType))

.header(HttpHeaders.CONTENT_DISPOSITION,

"attachment; filename=\"" + [Link]() + "\"")

.body(resource);

Page 44 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

19. Spring Boot Scheduling & Async

// Enable scheduling in main class or config

@SpringBootApplication

@EnableScheduling

@EnableAsync

public class MyAppApplication { ... }

// ■■ @Scheduled — Cron Jobs

@Service @Slf4j

public class ScheduledTasks {

// Fixed rate: every 5 seconds (regardless of task duration)

@Scheduled(fixedRate = 5000)

public void heartbeat() {

[Link]("Heartbeat: {}", [Link]());

// Fixed delay: 5 seconds AFTER previous task completes

@Scheduled(fixedDelay = 5000)

public void cleanupTempFiles() { ... }

// Cron expression: second minute hour day month weekday

@Scheduled(cron = "0 0 2 * * ?") // every day at 2:00 AM

public void dailyReport() { ... }

@Scheduled(cron = "0 0 8 * * MON-FRI") // weekdays at 8 AM

public void sendDailyEmails() { ... }

@Scheduled(cron = "0 */30 * * * ?") // every 30 minutes

public void syncData() { ... }

// ■■ @Async — non-blocking background tasks

Page 45 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

@Service

public class EmailService {

@Async // runs in a separate thread — caller doesn't wait

public CompletableFuture sendWelcomeEmail(String email) {

// Simulate email sending (slow I/O operation)

[Link](2000);

[Link]("Email sent to: {}", email);

return [Link](true);

// In service — fire and forget

[Link]([Link]()); // returns immediately

// Or await the result

CompletableFuture future = [Link](email);

boolean result = [Link](5, [Link]); // wait max 5s

■ Always configure a custom thread pool for @Async tasks to avoid exhausting the default pool: @Bean public
Executor asyncExecutor() { return new ThreadPoolTaskExecutor(); }

Page 46 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

20. Microservices with Spring Boot

Microservices architecture decomposes an application into small, independently deployable services. Spring
Cloud provides tools to build production-grade microservices ecosystems.

Component Technology Purpose

Service Registry Eureka Server (Spring Cloud) Services register & discover each other

API Gateway Spring Cloud Gateway Single entry point; routing, auth, rate limiting

Config Server Spring Cloud Config Centralized configuration for all services

Load Balancer Spring Cloud LoadBalancer Client-side load balancing

Circuit Breaker Resilience4j Fault tolerance — fallback when service fails

Inter-service RestTemplate / WebClient /


HTTP calls between services
Comms FeignClient

Distributed
Micrometer + Zipkin Trace requests across services
Tracing

Message Queue RabbitMQ / Kafka Async communication between services

// ■■ Eureka Client — register service for discovery

@SpringBootApplication

@EnableEurekaClient

public class UserServiceApplication { ... }

# [Link] — User Service

[Link]: user-service

[Link]: [Link]

// ■■ FeignClient — declarative REST client (like an interface)

@FeignClient(name = "order-service") // name = service registered in Eureka

public interface OrderServiceClient {

@GetMapping("/api/orders/user/{userId}")

List getOrdersByUserId(@PathVariable Long userId);

// Use in service like a normal bean:

@Service @RequiredArgsConstructor

Page 47 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

public class UserService {

private final OrderServiceClient orderServiceClient;

public UserWithOrdersDTO getUserWithOrders(Long userId) {

UserDTO user = findById(userId);

List orders = [Link](userId);

return new UserWithOrdersDTO(user, orders);

// ■■ Circuit Breaker with Resilience4j

@CircuitBreaker(name = "orderService", fallbackMethod = "getOrdersFallback")

public List getOrdersByUserId(Long userId) {

return [Link](userId);

public List getOrdersFallback(Long userId, Exception ex) {

[Link]("Order service down. Returning empty list for user {}", userId);

return [Link](); // graceful degradation

Page 48 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

21. Docker & Deployment

# ■■ Dockerfile for Spring Boot app

FROM eclipse-temurin:17-jdk-alpine AS build

WORKDIR /app

COPY [Link] .

COPY src ./src

RUN ./mvnw package -DskipTests

FROM eclipse-temurin:17-jre-alpine

WORKDIR /app

COPY --from=build /app/target/*.jar [Link]

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "[Link]"]

# ■■ Build & run Docker image

docker build -t my-spring-app .

docker run -d -p 8080:8080 --name my-app \

-e SPRING_PROFILES_ACTIVE=prod \

-e DB_PASSWORD=secret \

my-spring-app

# ■■ [Link] — app + MySQL + Redis

version: '3.8'

services:

app:

build: .

ports:

- '8080:8080'

environment:

- SPRING_PROFILES_ACTIVE=prod

- DB_URL=jdbc:mysql://db:3306/mydb

Page 49 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

- DB_USERNAME=root

- DB_PASSWORD=secret

depends_on:

- db

- redis

db:

image: mysql:8.0

environment:

MYSQL_ROOT_PASSWORD: secret

MYSQL_DATABASE: mydb

volumes:

- mysql-data:/var/lib/mysql

ports:

- '3306:3306'

redis:

image: redis:7-alpine

ports:

- '6379:6379'

volumes:

mysql-data:

# ■■ Commands

docker-compose up -d # start all services

docker-compose down # stop and remove containers

docker-compose logs -f app # follow app logs

Page 50 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

22. Key Annotations Cheat Sheet

■ Core / Component Scanning ■ Dependency Injection

@SpringBootApplica Main class: enables auto-config, @Autowired Inject Spring bean (prefer constructor
tion component scan, bean registration injection)

@Component Generic Spring-managed bean @Qualifier("name") Specify which bean to inject when
multiple exist
@Service @Component for service layer
(business logic) @Primary Default bean when multiple exist of
same type
@Repository @Component for DAO layer (exception
translation) @Value("${prop}") Inject a value from
[Link]
@Controller @Component for MVC controller
(returns views) @Scope("prototype" Change bean scope from singleton
)
@RestController @Controller + @ResponseBody
(returns JSON)

@Configuration Java config class that defines @Bean


methods

@Bean Declares a method that returns a


Spring-managed bean

■ Web / REST ■■ JPA / Persistence

@RequestMapping("/ Map URL path to class or method @Entity Marks class as a JPA database entity
path")
@Table(name='...') Specifies table name and constraints
@GetMapping / HTTP method shorthand
@Id Primary key field
@PostMapping /
@PutMapping / @GeneratedValue(ID Auto-generated primary key
@DeleteMapping / ENTITY)
@PatchMapping
@Column Map field to column (nullable, length,
@PathVariable Extract {id} from URL path unique)

@RequestParam Extract ?name=value from query string @OneToMany / JPA relationship types
@ManyToOne /
@RequestBody Deserialize JSON request body to Java
@ManyToMany /
object
@OneToOne
@ResponseBody Serialize return value to JSON
@JoinColumn(name=' Foreign key column definition
@ResponseStatus(Ht Set default HTTP response status ...')
[Link])
@Transactional Wraps method in database transaction
@CrossOrigin Enable CORS for the controller or
method

■ Security ■■ Scheduling / Async

@EnableWebSecurity Enable Spring Security @EnableScheduling Enable scheduled task support

@EnableMethodSecur Enable @PreAuthorize / @Scheduled(cron='. Cron-based or fixed-rate scheduled


ity @PostAuthorize ..') task

@PreAuthorize("exp Method-level auth check BEFORE @EnableAsync Enable async task support
ression") execution
@Async Run method in separate thread
@PostAuthorize("ex Method-level auth check AFTER
pression") execution

Page 51 • Spring Boot 3.x • Java 17+


■ Java Spring Boot — Complete Notes Pluto Academy • [Link]

■ Validation ■ Testing

@Valid Trigger validation on @RequestBody or @SpringBootTest Load full application context for
method parameter integration tests

@NotNull / Null/empty/blank checks @WebMvcTest(Contro Load only web layer (mock service
@NotBlank / [Link]) layer)
@NotEmpty
@DataJpaTest Load JPA layer with H2 in-memory
@Size(min,max) String/collection length constraint database

@Email / @Pattern Format validation @MockBean Create and register mock in Spring
context
@Min / @Max Numeric range
@Mock Create Mockito mock (unit tests without
Spring context)

@InjectMocks Inject @Mock dependencies into test


subject

■ You are now ready to build production Java backends!

Build real projects: Student Management System → E-Commerce API → Social Media Backend
Every concept in these notes should be implemented — not just read.

[Link] • @[Link] • MERN Stack & Java Backend Courses

Page 52 • Spring Boot 3.x • Java 17+

You might also like