0% found this document useful (0 votes)
10 views79 pages

Java Spring Complete Notes - MD

Uploaded by

yotaxar935
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)
10 views79 pages

Java Spring Complete Notes - MD

Uploaded by

yotaxar935
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

Complete Java Development: Spring Boot, Microservices, Spring AI

Comprehensive Course Notes by Telusko (61 Hours)

TABLE OF CONTENTS
1. Java Fundamentals Review
2. Spring Framework Core
3. Spring Boot Essentials
4. RESTful Web Services
5. Database Integration & JPA
6. Microservices Architecture
7. Spring Cloud Components
8. Security & Authentication
9. Spring AI Integration
10. Testing & Best Practices
11. Deployment & DevOps

1. JAVA FUNDAMENTALS REVIEW {#java-fundamentals}


1.1 Object-Oriented Programming (OOP)
Key Concepts:
Classes and Objects
Blueprint vs Instance
Constructor types (default, parameterized, copy)
Object lifecycle and garbage collection
Encapsulation
Private fields with public getters/setters
Access modifiers: private, protected, public, default
Data hiding principles
Inheritance
IS-A relationship
Method overriding vs overloading
super keyword usage
Single vs Multi-level inheritance
Polymorphism
Compile-time (method overloading)
Runtime (method overriding)
Abstract classes vs Interfaces
Dynamic method dispatch
Abstraction
Abstract classes
Interfaces and default methods (Java 8+)
When to use each

1.2 Java Collections Framework


Core Interfaces:
List: ArrayList, LinkedList, Vector
Use cases and performance characteristics
ArrayList for random access, LinkedList for insertions
Set: HashSet, TreeSet, LinkedHashSet
No duplicates allowed
TreeSet for sorted elements
Map: HashMap, TreeMap, LinkedHashMap, Hashtable
Key-value pairs
HashMap vs Hashtable (thread-safety)
ConcurrentHashMap for concurrent access
Queue: PriorityQueue, Deque
FIFO operations
Priority-based processing

Important Methods:
add(), remove(), contains(), size()
Iterator and enhanced for-loop
Stream API integration

1.3 Functional Programming (Java 8+)


Lambda Expressions:
java

// Syntax: (parameters) -> expression


[Link](item -> [Link](item));

Functional Interfaces:
Predicate<T> - boolean test(T t)
Function<T,R> - R apply(T t)
Consumer<T> - void accept(T t)
Supplier<T> - T get()

Stream API:
Intermediate operations: filter(), map(), sorted()
Terminal operations: collect(), forEach(), reduce()
Parallel streams for performance

Method References:
Static: ClassName::staticMethod
Instance: instance::instanceMethod
Constructor: ClassName::new

1.4 Exception Handling


Types:
Checked exceptions (compile-time)
Unchecked exceptions (runtime)
Errors (JVM issues)

Best Practices:
Try-catch-finally blocks
Try-with-resources (AutoCloseable)
Custom exceptions
Exception chaining
Never catch Exception/Throwable broadly

1.5 Multithreading & Concurrency


Thread Creation:
Extending Thread class
Implementing Runnable interface
Using ExecutorService

Synchronization:
synchronized keyword
Lock interface and ReentrantLock
volatile keyword
Atomic classes (AtomicInteger, etc.)

Concurrent Collections:
ConcurrentHashMap
CopyOnWriteArrayList
BlockingQueue

2. SPRING FRAMEWORK CORE {#spring-framework-core}


2.1 Introduction to Spring
What is Spring?
Lightweight framework for Java applications
Dependency Injection container
Aspect-Oriented Programming support
Transaction management
Data access abstraction

Spring Modules:
Core Container (IoC, Beans, Context)
Data Access/Integration (JDBC, ORM, JMS)
Web (MVC, WebSocket)
AOP (Aspect-Oriented Programming)
Test (Unit & Integration testing)

2.2 Inversion of Control (IoC) Container


Dependency Injection:
Objects don't create dependencies themselves
Container injects dependencies
Reduces coupling between classes

IoC Container Types:


BeanFactory (basic)
ApplicationContext (advanced, recommended)
ClassPathXmlApplicationContext
AnnotationConfigApplicationContext

2.3 Dependency Injection Types


Constructor Injection:

java

@Component
public class UserService {
private final UserRepository repository;

@Autowired
public UserService(UserRepository repository) {
[Link] = repository;
}
}

Pros: Immutability, required dependencies clear


Recommended for mandatory dependencies

Setter Injection:

java

@Component
public class UserService {
private UserRepository repository;

@Autowired
public void setRepository(UserRepository repository) {
[Link] = repository;
}
}

Pros: Optional dependencies, circular dependencies


Use for optional dependencies

Field Injection:

java

@Component
public class UserService {
@Autowired
private UserRepository repository;
}

Cons: Not recommended (testing issues, hidden dependencies)

2.4 Bean Lifecycle


Lifecycle Phases:
1. Bean instantiation
2. Populate properties
3. BeanNameAware's setBeanName()
4. BeanFactoryAware's setBeanFactory()
5. ApplicationContextAware's setApplicationContext()
6. PreInitialization (BeanPostProcessors)
7. InitializingBean's afterPropertiesSet()
8. Custom init-method
9. PostInitialization (BeanPostProcessors)
10. Bean ready for use
11. DisposableBean's destroy()
12. Custom destroy-method

Lifecycle Annotations:

java
@PostConstruct
public void init() {
// Initialization logic
}

@PreDestroy
public void cleanup() {
// Cleanup logic
}

2.5 Bean Scopes


Singleton (Default):
One instance per Spring container
Shared across application

Prototype:
New instance every time requested
Container doesn't manage complete lifecycle

Web Scopes:
Request: One instance per HTTP request
Session: One instance per HTTP session
Application: One instance per ServletContext
WebSocket: One instance per WebSocket session

java

@Component
@Scope("prototype")
public class PrototypeBean { }

2.6 Annotations
Core Annotations:
@Component - Generic stereotype
@Service - Service layer
@Repository - Data access layer
@Controller - Web layer (MVC)
@RestController - RESTful web services
@Configuration - Java-based configuration
@Bean - Bean definition in @Configuration
@Autowired - Dependency injection
@Qualifier - Specify which bean to inject
@Primary - Default bean when multiple candidates
@Value - Inject property values
@PropertySource - Load properties file

2.7 Configuration Methods


XML Configuration:

xml

<bean id="userService" class="[Link]">


<property name="repository" ref="userRepository"/>
</bean>

Java Configuration:

java

@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService(userRepository());
}
}

Annotation-based:

java

@ComponentScan(basePackages = "[Link]")
@Configuration
public class AppConfig { }

2.8 Aspect-Oriented Programming (AOP)


Key Concepts:
Aspect: Cross-cutting concern (logging, security)
Join Point: Point in program execution
Advice: Action taken at join point
Pointcut: Expression matching join points
Weaving: Linking aspects with objects

Advice Types:
@Before - Before method execution
@After - After method execution
@AfterReturning - After successful return
@AfterThrowing - After exception
@Around - Wrap method execution

Example:

java

@Aspect
@Component
public class LoggingAspect {

@Before("execution(* [Link].*.*(..))")
public void logBefore(JoinPoint joinPoint) {
[Link]("Executing: " + [Link]());
}
}

3. SPRING BOOT ESSENTIALS {#spring-boot-essentials}


3.1 What is Spring Boot?
Key Features:
Auto-configuration
Standalone applications (embedded servers)
Production-ready features (metrics, health checks)
No XML configuration required
Starter dependencies (curated dependencies)
Opinionated defaults

Advantages over Spring:


Faster development
Reduced boilerplate code
Embedded server (Tomcat, Jetty, Undertow)
Easy dependency management
Spring Boot CLI

3.2 Spring Boot Project Structure

src/
├── main/
│ ├── java/
│ │ └── com/example/myapp/
│ │ ├── [Link] (main class)
│ │ ├── controller/
│ │ ├── service/
│ │ ├── repository/
│ │ ├── model/
│ │ └── config/
│ └── resources/
│ ├── [Link] / [Link]
│ ├── static/ (CSS, JS, images)
│ └── templates/ (Thymeleaf, etc.)
└── test/
└── java/

3.3 Spring Boot Starters


Common Starters:
spring-boot-starter-web - Web applications, REST APIs
spring-boot-starter-data-jpa - JPA with Hibernate
spring-boot-starter-security - Spring Security
spring-boot-starter-test - Testing (JUnit, Mockito)
spring-boot-starter-validation - Bean Validation
spring-boot-starter-actuator - Monitoring & metrics
spring-boot-starter-cache - Caching support
spring-boot-starter-mail - Email support
spring-boot-starter-thymeleaf - Template engine

3.4 Application Properties Configuration


[Link]:

properties
[Link]=8080
[Link]=my-app

# Database
[Link]=jdbc:mysql://localhost:3306/mydb
[Link]=root
[Link]=secret

# JPA
[Link]-auto=update
[Link]-sql=true

# Logging
[Link]=INFO
[Link]=DEBUG

[Link] (YAML alternative):

yaml

server:
port: 8080

spring:
application:
name: my-app
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
jpa:
hibernate:
ddl-auto: update
show-sql: true

Profile-Specific Configuration:
[Link]
[Link]
Activate: [Link]=dev

3.5 Auto-Configuration
How it Works:
@SpringBootApplication enables auto-configuration
Scans classpath for libraries
Configures beans automatically
Conditional on presence of classes/beans

Main Annotation Breakdown:

java

@SpringBootApplication =
@SpringBootConfiguration +
@EnableAutoConfiguration +
@ComponentScan

Customizing Auto-Configuration:

java

@SpringBootApplication(exclude = {[Link]})
public class MyApp { }

3.6 Spring Boot DevTools


Features:
Automatic restart on code changes
LiveReload integration
Enhanced development experience
Property defaults for development

Setup:

xml

<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

3.7 Spring Boot Actuator


Endpoints:
/actuator/health - Application health
/actuator/info - Application info
/actuator/metrics - Application metrics
/actuator/env - Environment properties
/actuator/loggers - Logger configuration
/actuator/threaddump - Thread dump
/actuator/heapdump - Heap dump

Enable in [Link]:

properties

[Link]=health,info,metrics
[Link]-details=always

Custom Health Indicator:

java

@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// Check custom health logic
return [Link]().withDetail("custom", "All good").build();
}
}

4. RESTFUL WEB SERVICES {#restful-web-services}


4.1 REST Principles
Key Concepts:
REpresentational State Transfer
Stateless communication
Resource-based (URIs)
Standard HTTP methods
JSON/XML representations

REST Constraints:
1. Client-Server architecture
2. Stateless
3. Cacheable
4. Uniform interface
5. Layered system
6. Code on demand (optional)

4.2 HTTP Methods


CRUD Operations:
GET - Retrieve resource(s)
POST - Create new resource
PUT - Update/Replace entire resource
PATCH - Partial update
DELETE - Remove resource
OPTIONS - Supported methods
HEAD - Headers only

4.3 Building REST APIs


Basic Controller:

java
@RestController
@RequestMapping("/api/users")
public class UserController {

@Autowired
private UserService userService;

@GetMapping
public List<User> getAllUsers() {
return [Link]();
}

@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return [Link](id)
.map(ResponseEntity::ok)
.orElse([Link]().build());
}

@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User saved = [Link](user);
return [Link]([Link]).body(saved);
}

@PutMapping("/{id}")
public ResponseEntity<User> updateUser(
@PathVariable Long id,
@RequestBody User user) {
return [Link](id, user)
.map(ResponseEntity::ok)
.orElse([Link]().build());
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
[Link](id);
return [Link]().build();
}
}

4.4 Request/Response Handling


Path Variables:

java
@GetMapping("/users/{id}/posts/{postId}")
public Post getPost(@PathVariable Long id, @PathVariable Long postId) {
// Logic
}

Query Parameters:

java

@GetMapping("/users")
public List<User> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
// Logic
}

Request Headers:

java

@GetMapping("/users")
public List<User> getUsers(
@RequestHeader("Authorization") String token) {
// Logic
}

Request Body:

java

@PostMapping("/users")
public User createUser(@RequestBody User user) {
return [Link](user);
}

4.5 Validation
Bean Validation Annotations:

java
public class User {

@NotNull(message = "Name is required")


@Size(min = 2, max = 50)
private String name;

@Email(message = "Invalid email format")


private String email;

@Min(18)
@Max(100)
private Integer age;

@Pattern(regexp = "^\\+?[1-9]\\d{1,14}$")
private String phone;
}

Controller Validation:

java

@PostMapping("/users")
public ResponseEntity<?> createUser(@Valid @RequestBody User user,
BindingResult result) {
if ([Link]()) {
return [Link]().body([Link]());
}
return [Link]([Link](user));
}

4.6 Exception Handling


@ControllerAdvice:

java
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler([Link])
public ResponseEntity<ErrorResponse> handleNotFound(
ResourceNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
[Link](),
[Link]()
);
return [Link](HttpStatus.NOT_FOUND).body(error);
}

@ExceptionHandler([Link])
public ResponseEntity<Map<String, String>> handleValidation(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
[Link]().getFieldErrors().forEach(error ->
[Link]([Link](), [Link]())
);
return [Link]().body(errors);
}

@ExceptionHandler([Link])
public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"An error occurred",
[Link]()
);
return [Link](HttpStatus.INTERNAL_SERVER_ERROR)
.body(error);
}
}

4.7 Content Negotiation


Producing JSON/XML:

java
@GetMapping(value = "/users/{id}",
produces = {MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public User getUser(@PathVariable Long id) {
return [Link](id);
}

Consuming JSON/XML:

java

@PostMapping(value = "/users",
consumes = {MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public User createUser(@RequestBody User user) {
return [Link](user);
}

4.8 HATEOAS (Hypermedia)


Adding Links:

java

@GetMapping("/{id}")
public EntityModel<User> getUserById(@PathVariable Long id) {
User user = [Link](id);
EntityModel<User> resource = [Link](user);

[Link](linkTo(methodOn([Link])
.getUserById(id)).withSelfRel());
[Link](linkTo(methodOn([Link])
.getAllUsers()).withRel("users"));

return resource;
}

4.9 Pagination & Sorting


Using Pageable:

java
@GetMapping("/users")
public Page<User> getUsers(
@PageableDefault(size = 20, sort = "name") Pageable pageable) {
return [Link](pageable);
}

// URL: /users?page=0&size=10&sort=name,asc

4.10 Filtering & Search


Specification Pattern:

java

@GetMapping("/users/search")
public List<User> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) String email) {

Specification<User> spec = [Link](null);

if (name != null) {
spec = [Link]((root, query, cb) ->
[Link]([Link]("name"), "%" + name + "%"));
}

if (email != null) {
spec = [Link]((root, query, cb) ->
[Link]([Link]("email"), email));
}

return [Link](spec);
}

5. DATABASE INTEGRATION & JPA {#database-integration-jpa}


5.1 Spring Data JPA Overview
Benefits:
Reduces boilerplate code
Repository abstraction
Query derivation from method names
Pagination and sorting support
Custom queries with @Query

Key Interfaces:
Repository (marker)
CrudRepository (basic CRUD)
PagingAndSortingRepository (pagination)
JpaRepository (JPA-specific, recommended)

5.2 Entity Mapping


Basic Entity:

java

@Entity
@Table(name = "users")
public class User {

@Id
@GeneratedValue(strategy = [Link])
private Long id;

@Column(nullable = false, length = 50)


private String name;

@Column(unique = true, nullable = false)


private String email;

@Temporal([Link])
private Date birthDate;

@Enumerated([Link])
private UserRole role;

@CreationTimestamp
private LocalDateTime createdAt;

@UpdateTimestamp
private LocalDateTime updatedAt;

// Getters and setters


}

5.3 Relationships
One-to-One:
java

@Entity
public class User {
@Id
@GeneratedValue
private Long id;

@OneToOne(cascade = [Link])
@JoinColumn(name = "address_id", referencedColumnName = "id")
private Address address;
}

@Entity
public class Address {
@Id
@GeneratedValue
private Long id;

@OneToOne(mappedBy = "address")
private User user;
}

One-to-Many / Many-to-One:

java
@Entity
public class Department {
@Id
@GeneratedValue
private Long id;

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


private List<Employee> employees;
}

@Entity
public class Employee {
@Id
@GeneratedValue
private Long id;

@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
}

Many-to-Many:

java
@Entity
public class Student {
@Id
@GeneratedValue
private Long id;

@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private Set<Course> courses;
}

@Entity
public class Course {
@Id
@GeneratedValue
private Long id;

@ManyToMany(mappedBy = "courses")
private Set<Student> students;
}

5.4 Repository Methods


JpaRepository Interface:

java
public interface UserRepository extends JpaRepository<User, Long> {

// Query derivation
List<User> findByName(String name);
List<User> findByEmailContaining(String email);
List<User> findByAgeGreaterThan(Integer age);
List<User> findByNameAndEmail(String name, String email);
List<User> findByNameOrEmail(String name, String email);
List<User> findByOrderByNameAsc();

// Custom queries
@Query("SELECT u FROM User u WHERE [Link] = ?1")
Optional<User> findByEmail(String email);

@Query("SELECT u FROM User u WHERE [Link] LIKE %:name%")


List<User> searchByName(@Param("name") String name);

// Native queries
@Query(value = "SELECT * FROM users WHERE email = ?1",
nativeQuery = true)
User findByEmailNative(String email);

// Modifying queries
@Modifying
@Query("UPDATE User u SET [Link] = false WHERE [Link] = ?1")
void deactivateUser(Long id);

// Pagination
Page<User> findByNameContaining(String name, Pageable pageable);
}

5.5 Transaction Management


@Transactional Annotation:

java
@Service
public class UserService {

@Transactional
public void transferFunds(Long fromId, Long toId, BigDecimal amount) {
Account from = [Link](fromId)
.orElseThrow();
Account to = [Link](toId)
.orElseThrow();

[Link]([Link]().subtract(amount));
[Link]([Link]().add(amount));

[Link](from);
[Link](to);
}

@Transactional(readOnly = true)
public User getUserById(Long id) {
return [Link](id).orElseThrow();
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createAuditLog(String action) {
// Always creates new transaction
}
}

Transaction Attributes:
Propagation: REQUIRED, REQUIRES_NEW, NESTED, etc.
Isolation: READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ,
SERIALIZABLE
Timeout: Transaction timeout in seconds
ReadOnly: Optimization for read operations
Rollback: rollbackFor, noRollbackFor

5.6 N+1 Query Problem


Problem:

java
// Generates N+1 queries
List<Department> departments = [Link]();
for (Department dept : departments) {
[Link]().size(); // Lazy loading - extra query
}

Solutions:

java

// 1. JOIN FETCH
@Query("SELECT d FROM Department d JOIN FETCH [Link]")
List<Department> findAllWithEmployees();

// 2. @EntityGraph
@EntityGraph(attributePaths = {"employees"})
List<Department> findAll();

// 3. Batch Fetching
@Entity
public class Department {
@OneToMany
@BatchSize(size = 10)
private List<Employee> employees;
}

5.7 Caching
Enable Caching:

java

@SpringBootApplication
@EnableCaching
public class Application { }

Cache Annotations:

java
@Service
public class UserService {

@Cacheable(value = "users", key = "#id")


public User getUserById(Long id) {
return [Link](id).orElseThrow();
}

@CachePut(value = "users", key = "#[Link]")


public User updateUser(User user) {
return [Link](user);
}

@CacheEvict(value = "users", key = "#id")


public void deleteUser(Long id) {
[Link](id);
}

@CacheEvict(value = "users", allEntries = true)


public void clearCache() {
// Clears all entries
}
}

Cache Providers:
Simple (ConcurrentHashMap)
Caffeine
Redis
EhCache
Hazelcast

5.8 Auditing
Enable JPA Auditing:

java

@Configuration
@EnableJpaAuditing
public class JpaConfig { }

Auditable Entity:

java
@Entity
@EntityListeners([Link])
public class User {

@CreatedDate
private LocalDateTime createdDate;

@LastModifiedDate
private LocalDateTime lastModifiedDate;

@CreatedBy
private String createdBy;

@LastModifiedBy
private String lastModifiedBy;
}

AuditorAware Implementation:

java

@Component
public class AuditorAwareImpl implements AuditorAware<String> {

@Override
public Optional<String> getCurrentAuditor() {
// Get current user from security context
return [Link]("system");
}
}

6. MICROSERVICES ARCHITECTURE {#microservices-architecture}


6.1 Microservices Fundamentals
What are Microservices?
Architectural style
Application as suite of small services
Each service runs independently
Lightweight communication (HTTP/REST, messaging)
Independently deployable
Organized around business capabilities
Monolithic vs Microservices:
Monolithic:
Single deployable unit
Easier to develop initially
Difficult to scale specific features
Technology stack locked in

Microservices:
Multiple independent services
Complex infrastructure
Scale services independently
Technology diversity
Team autonomy

6.2 Microservices Design Principles


Key Principles:
1. Single Responsibility - One service, one business capability
2. Autonomy - Independent development and deployment
3. Resilience - Handle failures gracefully
4. Observability - Monitoring and logging
5. Automation - CI/CD pipelines
6. Decentralization - Data and governance

Service Boundaries:
Domain-Driven Design (DDD)
Bounded contexts
Business capabilities
Team structure (Conway's Law)

6.3 Service Communication Patterns


Synchronous:
REST APIs - HTTP/JSON
Simple, widely understood
Request/response coupling
Timeout issues
gRPC - Protocol Buffers
High performance
Strongly typed
Good for internal services

Asynchronous:
Message Queues - RabbitMQ, Amazon SQS
Decoupling
Load leveling
Retry mechanisms
Event Streaming - Kafka, AWS Kinesis
Event sourcing
Real-time processing
Event-driven architecture

6.4 API Gateway Pattern


Purpose:
Single entry point for clients
Request routing
Authentication/Authorization
Rate limiting
Request/Response transformation
Protocol translation

Implementation with Spring Cloud Gateway:

java
@Configuration
public class GatewayConfig {

@Bean
public RouteLocator customRoutes(RouteLocatorBuilder builder) {
return [Link]()
.route("user-service", r -> r
.path("/api/users/**")
.filters(f -> f
.stripPrefix(1)
.addRequestHeader("X-Gateway", "true"))
.uri("lb://USER-SERVICE"))
.route("order-service", r -> r
.path("/api/orders/**")
.filters(f -> [Link](1))
.uri("lb://ORDER-SERVICE"))
.build();
}
}

6.5 Service Discovery


Need:
Dynamic service instances
Services register themselves
Services discover others
Load balancing
Health checking

Netflix Eureka:
Eureka Server:

java

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication { }

[Link]:

yaml
server:
port: 8761

eureka:
client:
register-with-eureka: false
fetch-registry: false

Eureka Client:

java

@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication { }

[Link]:

yaml

spring:
application:
name: user-service

eureka:
client:
service-url:
defaultZone: [Link]
instance:
prefer-ip-address: true

6.6 Load Balancing


Client-Side Load Balancing (Spring Cloud LoadBalancer):

java
@Configuration
public class LoadBalancerConfig {

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

@Service
public class OrderService {

@Autowired
private RestTemplate restTemplate;

public User getUser(Long userId) {


return [Link](
"[Link] + userId,
[Link]
);
}
}

OpenFeign - Declarative REST Client:

java
@FeignClient(name = "user-service")
public interface UserClient {

@GetMapping("/users/{id}")
User getUserById(@PathVariable Long id);

@PostMapping("/users")
User createUser(@RequestBody User user);
}

@Service
public class OrderService {

@Autowired
private UserClient userClient;

public void processOrder(Order order) {


User user = [Link]([Link]());
// Process order
}
}

6.7 Circuit Breaker Pattern (Resilience4j)


Purpose:
Prevent cascading failures
Fail fast when service unavailable
Automatic recovery detection

States:
Closed: Normal operation
Open: Service down, reject requests
Half-Open: Test if service recovered

Implementation:

java
@Service
public class UserService {

@CircuitBreaker(name = "userService", fallbackMethod = "getUserFallback")


public User getUser(Long id) {
return [Link](
"[Link] + id,
[Link]
);
}

private User getUserFallback(Long id, Exception e) {


return new User(id, "Default User", "default@[Link]");
}
}

Configuration:

yaml

resilience4j:
circuitbreaker:
instances:
userService:
sliding-window-size: 10
failure-rate-threshold: 50
wait-duration-in-open-state: 10000
permitted-number-of-calls-in-half-open-state: 3

Other Resilience Patterns:


Retry: Automatic retries with backoff
Rate Limiter: Limit concurrent calls
Bulkhead: Isolate resources
Time Limiter: Timeout for operations

6.8 Distributed Tracing


Spring Cloud Sleuth + Zipkin:
Setup:

xml
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

Configuration:

yaml

spring:
sleuth:
sampler:
probability: 1.0 # Sample 100% of requests
zipkin:
base-url: [Link]

Features:
Trace ID: Unique ID across all services
Span ID: ID for each operation
Correlation: Track request flow
Performance analysis

6.9 Centralized Configuration


Spring Cloud Config Server:
Config Server:

java

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication { }

[Link]:

yaml
server:
port: 8888

spring:
cloud:
config:
server:
git:
uri: [Link]
default-label: main

Config Client:

yaml

spring:
application:
name: user-service
config:
import: optional:configserver:[Link]

Refresh Configuration:
@RefreshScope annotation
POST to /actuator/refresh
Spring Cloud Bus for broadcasting

6.10 Database Per Service


Strategies:
Database per service - Complete isolation
Shared database - Anti-pattern (couples services)
Saga pattern - Distributed transactions
CQRS - Separate read/write models

Saga Pattern:

java
// Orchestration-based Saga
@Service
public class OrderSagaOrchestrator {

public void createOrder(Order order) {


try {
// Step 1: Reserve inventory
[Link]([Link]());

// Step 2: Process payment


[Link]([Link]());

// Step 3: Create order


[Link](order);

} catch (Exception e) {
// Compensating transactions
[Link]([Link]());
[Link]([Link]());
throw new OrderCreationException(e);
}
}
}

7. SPRING CLOUD COMPONENTS {#spring-cloud-components}


7.1 Spring Cloud Config
Features:
Centralized external configuration
Environment-specific properties
Encryption/Decryption
Refresh without restart
Git, SVN, filesystem backends

Repository Structure:
config-repo/
├── [Link] (default)
├── [Link]
├── [Link]
├── [Link]
└── [Link]

Property Hierarchy:
1. [Link] (lowest priority)
2. application-{profile}.yml
3. {service-name}.yml
4. {service-name}-{profile}.yml (highest priority)

7.2 Spring Cloud Gateway


Features:
Built on Spring WebFlux
Route matching
Filters (pre/post)
Predicates
Rate limiting
Circuit breakers

Route Configuration:

yaml
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- AddRequestHeader=X-Request-From, Gateway

- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/api/orders/**
- Method=GET,POST
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: orderServiceCB
fallbackUri: forward:/fallback/orders

Custom Filter:

java
@Component
public class CustomFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
ServerHttpRequest request = [Link]();
[Link]("Request: " + [Link]());

return [Link](exchange).then([Link](() -> {


ServerHttpResponse response = [Link]();
[Link]("Response: " + [Link]());
}));
}

@Override
public int getOrder() {
return -1; // Highest priority
}
}

7.3 Spring Cloud Stream


Messaging Abstraction:
Binder abstraction (Kafka, RabbitMQ)
Declarative bindings
Message-driven microservices
Event-driven architecture

Producer:

java

@Service
public class OrderEventProducer {

@Autowired
private StreamBridge streamBridge;

public void sendOrderEvent(Order order) {


OrderEvent event = new OrderEvent(order);
[Link]("order-out-0", event);
}
}
Consumer:

java

@Component
public class OrderEventConsumer {

@Bean
public Consumer<OrderEvent> processOrder() {
return event -> {
[Link]("Received: " + event);
// Process order event
};
}
}

Configuration:

yaml

spring:
cloud:
stream:
bindings:
processOrder-in-0:
destination: orders
group: order-service
order-out-0:
destination: orders
kafka:
binder:
brokers: localhost:9092

7.4 Spring Cloud Bus


Features:
Link nodes with message broker
Broadcast state changes
Configuration refresh
Custom events

Setup:

yaml
spring:
rabbitmq:
host: localhost
port: 5672

Refresh All Services:

bash

curl -X POST [Link]

7.5 Spring Cloud OpenFeign


Advanced Features:
Configuration:

java

@Configuration
public class FeignConfig {

@Bean
public RequestInterceptor requestInterceptor() {
return template -> {
[Link]("X-Custom-Header", "value");
};
}

@Bean
public [Link] feignLoggerLevel() {
return [Link];
}
}

Error Decoder:

java
public class CustomErrorDecoder implements ErrorDecoder {

@Override
public Exception decode(String methodKey, Response response) {
if ([Link]() == 404) {
return new ResourceNotFoundException("Resource not found");
}
return new Exception("Generic error");
}
}

Fallback:

java

@FeignClient(name = "user-service", fallback = [Link])


public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable Long id);
}

@Component
public class UserClientFallback implements UserClient {
@Override
public User getUser(Long id) {
return new User(id, "Default", "default@[Link]");
}
}

8. SECURITY & AUTHENTICATION {#security-authentication}


8.1 Spring Security Fundamentals
Core Concepts:
Authentication - Who are you?
Authorization - What can you do?
Principal - Currently authenticated user
Granted Authority - Permissions
Roles - Groups of authorities

Security Filter Chain:


1. SecurityContextPersistenceFilter
2. UsernamePasswordAuthenticationFilter
3. BasicAuthenticationFilter
4. ExceptionTranslationFilter
5. FilterSecurityInterceptor

8.2 Basic Security Configuration

java

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http)
throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/api/**").authenticated()
.anyRequest().authenticated()
)
.httpBasic()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();

return [Link]();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

8.3 UserDetailsService Implementation

java
@Service
public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {

User user = [Link](username)


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

return [Link]
.builder()
.username([Link]())
.password([Link]())
.roles([Link]().toArray(new String[0]))
.build();
}
}

8.4 JWT Authentication


JWT Structure:
Header: Algorithm and token type
Payload: Claims (user data)
Signature: Verification

JWT Utility:

java
@Component
public class JwtUtil {

private String secret = "your-secret-key";


private long expiration = 86400000; // 24 hours

public String generateToken(UserDetails userDetails) {


Map<String, Object> claims = new HashMap<>();
return [Link]()
.setClaims(claims)
.setSubject([Link]())
.setIssuedAt(new Date())
.setExpiration(new Date([Link]() + expiration))
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}

public String extractUsername(String token) {


return extractClaim(token, Claims::getSubject);
}

public boolean validateToken(String token, UserDetails userDetails) {


String username = extractUsername(token);
return [Link]([Link]())
&& !isTokenExpired(token);
}

private boolean isTokenExpired(String token) {


return extractExpiration(token).before(new Date());
}

private Date extractExpiration(String token) {


return extractClaim(token, Claims::getExpiration);
}

private <T> T extractClaim(String token,


Function<Claims, T> claimsResolver) {
Claims claims = [Link]()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
return [Link](claims);
}
}

JWT Filter:
java
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired
private JwtUtil jwtUtil;

@Autowired
private CustomUserDetailsService userDetailsService;

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {

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

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


String token = [Link](7);
String username = [Link](token);

if (username != null &&


[Link]().getAuthentication() == null) {

UserDetails userDetails =
[Link](username);

if ([Link](token, userDetails)) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, [Link]());

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

[Link]()
.setAuthentication(authToken);
}
}
}

[Link](request, response);
}
}
Authentication Controller:

java

@RestController
@RequestMapping("/api/auth")
public class AuthController {

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private JwtUtil jwtUtil;

@Autowired
private CustomUserDetailsService userDetailsService;

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
try {
[Link](
new UsernamePasswordAuthenticationToken(
[Link](),
[Link]()
)
);
} catch (BadCredentialsException e) {
throw new BadCredentialsException("Invalid credentials");
}

UserDetails userDetails =
[Link]([Link]());
String token = [Link](userDetails);

return [Link](new AuthResponse(token));


}
}

8.5 OAuth2 and Social Login


OAuth2 Flow:
1. User redirected to provider (Google, GitHub)
2. User grants permission
3. Provider redirects back with authorization code
4. Application exchanges code for access token
5. Use token to access user info
Configuration:

yaml

spring:
security:
oauth2:
client:
registration:
google:
client-id: your-client-id
client-secret: your-client-secret
scope: profile, email
github:
client-id: your-client-id
client-secret: your-client-secret

Security Config:

java

@Configuration
public class OAuth2SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService());

return [Link]();
}
}

8.6 Method-Level Security

java
@Configuration
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true
)
public class MethodSecurityConfig { }

Annotations:

java

@Service
public class UserService {

@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) {
[Link](id);
}

@PreAuthorize("hasAuthority('WRITE_PRIVILEGE')")
public User updateUser(User user) {
return [Link](user);
}

@PreAuthorize("#username == [Link]")
public User getUser(String username) {
return [Link](username);
}

@PostAuthorize("[Link] == [Link]")
public Document getDocument(Long id) {
return [Link](id);
}

@Secured({"ROLE_ADMIN", "ROLE_MANAGER"})
public void approveDocument(Long id) {
// Logic
}
}

8.7 CORS Configuration

java
@Configuration
public class CorsConfig {

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
[Link](
[Link]("[Link] "[Link]
[Link](
[Link]("GET", "POST", "PUT", "DELETE", "OPTIONS"));
[Link]([Link]("*"));
[Link](true);

UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
[Link]("/**", configuration);
return source;
}
}

8.8 CSRF Protection


Enable CSRF:

java

[Link]()
.csrfTokenRepository([Link]());

Disable for APIs:

java

[Link]().disable(); // For stateless REST APIs with JWT

9. SPRING AI INTEGRATION {#spring-ai-integration}


9.1 Introduction to Spring AI
What is Spring AI?
Framework for AI-powered applications
Abstraction over AI providers (OpenAI, Azure, etc.)
Chat completion
Embeddings
Vector databases
Prompt templates
Key Components:
AI Models (Chat, Embedding)
Vector Stores
Document Readers
Prompt Templates
Output Parsers

9.2 Setting Up Spring AI


Dependencies:

xml

<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

Configuration:

yaml

spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4
temperature: 0.7

9.3 Chat Completion


Basic Usage:

java
@Service
public class AiChatService {

@Autowired
private ChatClient chatClient;

public String chat(String message) {


ChatResponse response = [Link](
new Prompt(message)
);
return [Link]().getOutput().getContent();
}

public String chatWithHistory(List<Message> messages) {


ChatResponse response = [Link](
new Prompt(messages)
);
return [Link]().getOutput().getContent();
}
}

Streaming Response:

java

public Flux<String> chatStream(String message) {


return [Link](new Prompt(message))
.map(response -> [Link]().getOutput().getContent());
}

9.4 Prompt Templates


Template Usage:

java
@Service
public class PromptService {

public String generateProductDescription(String product) {


String template = """
Generate a compelling product description for: {product}

Include:
- Key features
- Benefits
- Target audience

Keep it under 100 words.


""";

PromptTemplate promptTemplate = new PromptTemplate(template);


[Link]("product", product);

return [Link]([Link]())
.getResult().getOutput().getContent();
}
}

System Messages:

java

public String chatWithSystemMessage(String userMessage) {


List<Message> messages = [Link](
new SystemMessage("You are a helpful customer support assistant."),
new UserMessage(userMessage)
);

return [Link](new Prompt(messages))


.getResult().getOutput().getContent();
}

9.5 Embeddings and Vector Stores


Generate Embeddings:

java
@Service
public class EmbeddingService {

@Autowired
private EmbeddingClient embeddingClient;

public List<Double> generateEmbedding(String text) {


EmbeddingResponse response = [Link](
[Link](text)
);
return [Link]().get(0).getOutput();
}
}

Vector Store Integration:

java

@Configuration
public class VectorStoreConfig {

@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
return new SimpleVectorStore(embeddingClient);
}
}

@Service
public class DocumentService {

@Autowired
private VectorStore vectorStore;

public void addDocument(String content, Map<String, Object> metadata) {


Document document = new Document(content, metadata);
[Link]([Link](document));
}

public List<Document> searchSimilar(String query, int topK) {


return [Link](
[Link](query).withTopK(topK)
);
}
}

9.6 Retrieval Augmented Generation (RAG)


RAG Pattern:
1. User asks question
2. Generate embedding for question
3. Search vector store for relevant documents
4. Combine documents with question as context
5. Send to AI model
6. Return enhanced response

Implementation:

java
@Service
public class RagService {

@Autowired
private VectorStore vectorStore;

@Autowired
private ChatClient chatClient;

public String answerQuestion(String question) {


// 1. Search for relevant documents
List<Document> relevantDocs = [Link](
[Link](question).withTopK(3)
);

// 2. Build context from documents


String context = [Link]()
.map(Document::getContent)
.collect([Link]("\n\n"));

// 3. Create prompt with context


String promptText = [Link]("""
Context:
%s

Question: %s

Answer based on the context above:


""", context, question);

// 4. Get AI response
return [Link](new Prompt(promptText))
.getResult().getOutput().getContent();
}
}

9.7 Function Calling


Define Functions:

java
@Configuration
public class FunctionConfig {

@Bean
@Description("Get current weather for a location")
public Function<WeatherRequest, WeatherResponse> getWeather() {
return request -> {
// Call weather API
return new WeatherResponse(
[Link](),
72,
"Sunny"
);
};
}
}

record WeatherRequest(String location) {}


record WeatherResponse(String location, int temperature, String condition) {}

Use Functions:

java

@Service
public class FunctionCallingService {

@Autowired
private ChatClient chatClient;

public String chatWithFunctions(String message) {


ChatResponse response = [Link](
new Prompt(
message,
[Link]()
.withFunction("getWeather")
.build()
)
);

return [Link]().getOutput().getContent();
}
}
9.8 Document Processing
Load and Process Documents:

java

@Service
public class DocumentProcessor {

@Autowired
private VectorStore vectorStore;

public void processDocument(Resource resource) {


// Read document
PdfDocumentReader reader = new PdfDocumentReader(resource);
List<Document> documents = [Link]();

// Split into chunks


TextSplitter splitter = new TokenTextSplitter();
List<Document> chunks = [Link](documents);

// Add to vector store


[Link](chunks);
}
}

9.9 Output Parsing


Structured Output:

java
public record Product(String name, String category, double price) {}

@Service
public class OutputParserService {

@Autowired
private ChatClient chatClient;

public Product extractProduct(String text) {


BeanOutputParser<Product> parser =
new BeanOutputParser<>([Link]);

String promptText = """


Extract product information from: %s

%s
""".formatted(text, [Link]());

ChatResponse response = [Link](


new Prompt(promptText)
);

return [Link](
[Link]().getOutput().getContent()
);
}
}

9.10 AI-Powered REST API


Complete Example:

java
@RestController
@RequestMapping("/api/ai")
public class AiController {

@Autowired
private AiChatService chatService;

@Autowired
private RagService ragService;

@PostMapping("/chat")
public ResponseEntity<String> chat(@RequestBody ChatRequest request) {
String response = [Link]([Link]());
return [Link](response);
}

@PostMapping("/chat/stream")
public Flux<String> chatStream(@RequestBody ChatRequest request) {
return [Link]([Link]());
}

@PostMapping("/ask")
public ResponseEntity<String> askQuestion(
@RequestBody QuestionRequest request) {
String answer = [Link]([Link]());
return [Link](answer);
}

@PostMapping("/documents")
public ResponseEntity<Void> uploadDocument(
@RequestParam("file") MultipartFile file) {
// Process and store document
return [Link]().build();
}
}

record ChatRequest(String message) {}


record QuestionRequest(String question) {}

10. TESTING & BEST PRACTICES {#testing-best-practices}


10.1 Unit Testing
JUnit 5 Basics:
java

@SpringBootTest
public class UserServiceTest {

@Mock
private UserRepository userRepository;

@InjectMocks
private UserService userService;

@BeforeEach
void setUp() {
[Link](this);
}

@Test
void testGetUserById_Success() {
// Arrange
User user = new User(1L, "John", "john@[Link]");
when([Link](1L))
.thenReturn([Link](user));

// Act
User result = [Link](1L);

// Assert
assertNotNull(result);
assertEquals("John", [Link]());
verify(userRepository, times(1)).findById(1L);
}

@Test
void testGetUserById_NotFound() {
// Arrange
when([Link](999L))
.thenReturn([Link]());

// Act & Assert


assertThrows([Link], () -> {
[Link](999L);
});
}
}
10.2 Integration Testing
Repository Tests:

java

@DataJpaTest
public class UserRepositoryTest {

@Autowired
private UserRepository userRepository;

@Autowired
private TestEntityManager entityManager;

@Test
void testFindByEmail() {
// Arrange
User user = new User("John", "john@[Link]");
[Link](user);
[Link]();

// Act
Optional<User> found = [Link]("john@[Link]");

// Assert
assertTrue([Link]());
assertEquals("John", [Link]().getName());
}
}

Controller Tests:

java
@WebMvcTest([Link])
public class UserControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private UserService userService;

@Test
void testGetAllUsers() throws Exception {
// Arrange
List<User> users = [Link](
new User(1L, "John", "john@[Link]"),
new User(2L, "Jane", "jane@[Link]")
);
when([Link]()).thenReturn(users);

// Act & Assert


[Link](get("/api/users"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].name", is("John")))
.andExpect(jsonPath("$[1].name", is("Jane")));
}

@Test
void testCreateUser() throws Exception {
// Arrange
User user = new User(null, "John", "john@[Link]");
User saved = new User(1L, "John", "john@[Link]");
when([Link](any([Link]))).thenReturn(saved);

// Act & Assert


[Link](post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\":\"John\",\"email\":\"john@[Link]\"}"))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.id", is(1)))
.andExpect(jsonPath("$.name", is("John")));
}
}

10.3 Test Containers


Database Integration:
java

@SpringBootTest
@Testcontainers
public class UserServiceIntegrationTest {

@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
"postgres:15-alpine"
);

@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
[Link]("[Link]", postgres::getJdbcUrl);
[Link]("[Link]", postgres::getUsername);
[Link]("[Link]", postgres::getPassword);
}

@Autowired
private UserService userService;

@Test
void testUserCreation() {
User user = new User("John", "john@[Link]");
User saved = [Link](user);

assertNotNull([Link]());
assertEquals("John", [Link]());
}
}

10.4 Best Practices


Coding Standards:
Follow SOLID principles
Use meaningful names
Keep methods small
DRY (Don't Repeat Yourself)
Write self-documenting code

Project Structure:
[Link]/
├── controller/
├── service/
│ ├── impl/
├── repository/
├── model/
│ ├── entity/
│ ├── dto/
├── exception/
├── config/
├── security/
└── util/

DTOs and Entities:

java

// Separate Entity from DTO


@Entity
public class User {
@Id
private Long id;
private String name;
private String password; // Sensitive
}

public class UserDTO {


private Long id;
private String name;
// No password field
}

// Mapper
@Component
public class UserMapper {
public UserDTO toDTO(User user) {
return new UserDTO([Link](), [Link]());
}
}

Error Handling:

java
// Custom exception hierarchy
public class BusinessException extends RuntimeException {
private final ErrorCode errorCode;
}

public class ResourceNotFoundException extends BusinessException {


public ResourceNotFoundException(String message) {
super(ErrorCode.RESOURCE_NOT_FOUND, message);
}
}

Logging:

java

@Service
@Slf4j
public class UserService {

public User getUserById(Long id) {


[Link]("Fetching user with id: {}", id);

try {
User user = [Link](id)
.orElseThrow(() -> new ResourceNotFoundException("User not found"));
[Link]("Successfully retrieved user: {}", id);
return user;
} catch (Exception e) {
[Link]("Error fetching user: {}", id, e);
throw e;
}
}
}

Performance Optimization:
Use pagination for large datasets
Implement caching strategically
Optimize database queries (avoid N+1)
Use connection pooling
Implement rate limiting
Use async processing for heavy tasks
11. DEPLOYMENT & DEVOPS {#deployment-devops}
11.1 Docker
Dockerfile:

dockerfile

FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/[Link] [Link]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "[Link]"]

Multi-stage Build:

dockerfile

# Build stage
FROM maven:3.8-openjdk-17 AS build
WORKDIR /app
COPY [Link] .
COPY src ./src
RUN mvn clean package -DskipTests

# Run stage
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY --from=build /app/target/[Link] [Link]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "[Link]"]

Docker Compose:

yaml
version: '3.8'

services:
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb
- SPRING_DATASOURCE_USERNAME=postgres
- SPRING_DATASOURCE_PASSWORD=secret
depends_on:
- db
- redis

db:
image: postgres:15-alpine
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
volumes:
- postgres-data:/var/lib/postgresql/data

redis:
image: redis:7-alpine
ports:
- "6379:6379"

volumes:
postgres-data:

11.2 Kubernetes
Deployment:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0.0
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10

Service:

yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer

ConfigMap:

yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
data:
[Link]: |
[Link]=8080
[Link]=jdbc:postgresql://postgres:5432/mydb

11.3 CI/CD Pipeline


GitHub Actions:

yaml
name: CI/CD Pipeline

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Set up JDK 17


uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

- name: Build with Maven


run: mvn clean package

- name: Run tests


run: mvn test

- name: Build Docker image


run: docker build -t myapp:${{ [Link] }} .

- name: Push to Docker Hub


run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USE
docker push myapp:${{ [Link] }}

- name: Deploy to Kubernetes


run: |
kubectl set image deployment/myapp myapp=myapp:${{ [Link] }}

11.4 Monitoring and Logging


Prometheus + Grafana:

yaml
# [Link]
management:
endpoints:
web:
exposure:
include: prometheus,health,info,metrics
metrics:
export:
prometheus:
enabled: true

ELK Stack (Elasticsearch, Logstash, Kibana):

xml

<!-- [Link] -->


<configuration>
<appender name="JSON" class="[Link]">
<encoder class="[Link]"/>
</appender>

<root level="INFO">
<appender-ref ref="JSON"/>
</root>
</configuration>

11.5 Production Checklist


Before Deployment:
All tests passing
Security scan completed
Performance testing done
Database migrations ready
Environment variables configured
Logging configured
Monitoring setup
Backup strategy in place
Rollback plan documented
Health checks configured
Rate limiting implemented
HTTPS enabled
CORS configured properly
Secrets management setup
Documentation updated

ADDITIONAL RESOURCES
Recommended Learning Path
1. Java Fundamentals (if needed)
2. Spring Core - IoC, DI, AOP
3. Spring Boot - Auto-configuration, Starters
4. REST APIs - Controllers, DTOs, Validation
5. Database - JPA, Hibernate, Transactions
6. Testing - Unit, Integration tests
7. Microservices - Architecture, patterns
8. Spring Cloud - Gateway, Config, Discovery
9. Security - Authentication, Authorization, JWT
10. Spring AI - Chat, Embeddings, RAG
11. DevOps - Docker, Kubernetes, CI/CD

Practice Projects
1. Blog API - CRUD, authentication, comments
2. E-commerce - Products, cart, orders, payments
3. Task Management - Projects, tasks, assignments
4. Social Media - Posts, likes, follows, feeds
5. Chat Application - Real-time messaging, WebSocket
6. AI Chatbot - Spring AI, RAG, document search

Key Takeaways
Spring Boot simplifies Spring development
Microservices enable scalability and flexibility
Proper testing ensures reliability
Security is not optional
Spring AI makes AI integration straightforward
DevOps practices are essential for production
QUICK REFERENCE
Common Annotations
@SpringBootApplication - Main application class
@RestController - REST controller
@Service - Service layer
@Repository - Data access layer
@Component - Generic component
@Autowired - Dependency injection
@GetMapping - HTTP GET endpoint
@PostMapping - HTTP POST endpoint
@PutMapping - HTTP PUT endpoint
@DeleteMapping - HTTP DELETE endpoint
@PathVariable - Extract path variable
@RequestParam - Extract query parameter
@RequestBody - Parse request body
@Valid - Enable validation
@Transactional - Transaction boundary
@Cacheable - Enable caching
@Async - Asynchronous execution

Useful Commands

bash
# Build project
mvn clean package

# Run application
mvn spring-boot:run

# Run tests
mvn test

# Build Docker image


docker build -t myapp .

# Run Docker container


docker run -p 8080:8080 myapp

# Docker Compose
docker-compose up -d

# Kubernetes
kubectl apply -f [Link]
kubectl get pods
kubectl logs <pod-name>

End of Notes

You might also like