0% found this document useful (0 votes)
2 views20 pages

Unit V

The Spring Framework is a comprehensive Java framework that simplifies the development of enterprise applications through dependency injection and inversion of control. Spring Boot enhances this by providing an easy way to set up and manage Spring applications, allowing developers to focus on business logic rather than configuration. Key features include support for various application types, modular architecture, and tools for managing beans and their lifecycles.

Uploaded by

Pankaj Garg
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)
2 views20 pages

Unit V

The Spring Framework is a comprehensive Java framework that simplifies the development of enterprise applications through dependency injection and inversion of control. Spring Boot enhances this by providing an easy way to set up and manage Spring applications, allowing developers to focus on business logic rather than configuration. Key features include support for various application types, modular architecture, and tools for managing beans and their lifecycles.

Uploaded by

Pankaj Garg
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
You are on page 1/ 20

Spring Framework

Spring Boot is a way for Java developers to work with the Spring Framework in an easy way. Now, before you
use Spring Boot you need to understand what the Spring Framework is all about. If you've been a Java developer
for any length of time, it's quite likely that you've used some component or the other, which is part of the Spring
Framework because Spring is a Java framework that provides a convenient way of integrating disparate
components into a working enterprise-grade application. The Spring Framework relies heavily on inversion of
control to bring these components together.
Managing dependencies within your
application is a hard task, especially
in Java, when you have several
libraries that you could depend on
to get your task done. Inversion of
Control, implemented using
dependency injection, makes this
easy in Spring. A common scenario
which you might have encountered
is to use Spring modules such as
Spring MVC to build web applications, but Spring is so much more. Spring refers to an entire family of projects
which support a wide range of applications. Spring supports a wide range of enterprise-grade applications,
whether they are web applications, long running batch processing jobs or any other kind. You can use Spring with
simple cloud-hosted servers, standalone batch workloads and integration workloads. A common factor that you'll
encounter across all enterprise-grade applications is their complexity.

It focuses on the plumbing so that


individual teams can focus on
application level business logic without
worrying about how all of them fit
together. To bring together disparate
components to work as a single
application, Spring relies heavily on the
principle of inversion of control (IoC) to
achieve this. Inversion of control is a
principal in software engineering by
which the control of objects or portions of a program is transferred to the container or framework within which
the program runs. There are different components which perform different actions, and these components must
interact with one another. These components might be dependent on one another.

The Spring framework itself can be thought of as an infrastructure platform that brings all of these disparate
components together and gets them working together as a whole in an application or a product that you have
built. The cool thing about working with Spring is that you can write development code using POJOs, or Plain Old
Spring Framework
Java Objects. A POJO is just a Java class that you
define to represent any entity within your
application that is not tied to any specific
framework.
Spring allows you to work with POJOs. Spring has
been developed so that it can work with the Java
Standard Edition. Spring also has support for the
Java Enterprise Edition.

Spring allows you to set up database transactions


with simple Java methods without having to deal
with transaction APIs. Spring makes it very easy for you to expose HTTP endpoints from your applications that
can respond to HTTP request. These HTTP endpoints can be set up without you having to deal with Servlet APIs.
Spring allows you to configure message handlers, which can send messages between the components of your
application and you don't have to deal with the Java Messaging Service APIs directly and finally, when you work
with the Spring Framework, you get monitoring
support without dealing directly with JMX APIs.

Spring allows you to harness the functionality


provided in its different modules in a
straightforward manner. Here is a big picture
view of how exactly the Spring Framework
works. When you're working with Spring, you're
typically writing your code in the form of
business objects that are POJOs or plain old
Java objects. These POJOs, which are your
business objects, will be managed by the Spring
container. In addition, you might specify
additional configuration metadata for your object. This can be via Java annotations or via XML configuration files.
This configuration metadata will be applied to your business objects, and in the end, you'll get a fully configured
system that is ready for use.

Here is a big picture view of the modules included as a part of the Spring Framework runtime. You have data
access and integration modules that use JDBC, ORM frameworks such as Hibernate. All of these serve to abstract
you away from the transaction mechanics of the underlying database. You have a web related modules as well,
which help you build REST services and web
applications. You have modules that enable Aspect
Oriented Programming (AOP), where you can write
code to extend the functionality of existing
components. You have modules for instrumentation
and messaging as well.

2
Spring Framework
Spring Dependency Injection (DI) Concepts
Dependency Injection (DI) is a design pattern used to reduce coupling between components. Instead of
a class creating its dependencies, Spring Framework injects those dependencies at runtime.

Advantages of Dependency Injections

• Promotes loose coupling


• Improves testability and maintainability
• Encourages separation of concerns
• Make code easier to manage and scale

Types of Dependency Injection

1. Constructor Injection - Dependencies are provided via the class constructor.


2. Setter Injection - Dependencies are set using setter methods.
3. Field Injection - Dependencies are injected directly into fields using annotations.

Example Constructor and Setter Injection


public class Engine {
public void start() {
System.out.println("Engine started...");
}
}
Constructor Injection Example
@Component
public class Car {
private Engine engine;

// Constructor Injection
@Autowired
public Car(Engine engine) {
this.engine = engine;
}

public void drive() {


engine.start();
System.out.println("Car is moving...");
}
}

Setter Injection Example


@Component
public class Car {
private Engine engine;

// Setter Injection
@Autowired

3
Spring Framework
public void setEngine(Engine engine) {
this.engine = engine;
}

public void drive() {


engine.start();
System.out.println("Car is moving...");
}
}

Configuration and Running


@SpringBootApplication
public class MyApp implements CommandLineRunner {

@Autowired
private Car car;

public static void main(String[] args) {


SpringApplication.run(MyApp.class, args);
}

@Override
public void run(String... args) {
car.drive();
}
}
Note
• Use @Component to mark classes for Spring to manage.
• Use @Autowired for automatic injection (can be used on constructors, setters, or fields).
• Constructor Injection is recommended for required dependencies and better immutability.
Alternative to @Component
• @Service – for service classes
• @Repository – for DAO classes
• @Controller – for web controllers

Flowchart

4
Spring Framework
Inversion of Control (IoC)
Inversion of Control (IoC) is a principle in which the control of object creation and lifecycle management
is shifted from the application code to the Spring container. In simple term “YOU don’t create objects.
Spring does it for you and injects them where needed.” IoC is implemented in Spring via Dependency
Injection.

IOC Vs Traditional Control


Aspect Traditional Approach IoC Approach
Object Creation Manual creation using new keyword Spring creates and manages
Dependency Management Tight coupling Loose coupling
Testing Harder Easier

Example without IoC vs With IoC


Without IoC (Tight coupling)
public class Car {
private Engine engine;

public Car() {
this.engine = new Engine(); // tightly coupled
}

public void drive() {


engine.start();
System.out.println("Driving...");
}
}

Here, Car controls how Engine is created — violates IoC.

With IoC using Spring (Loose Coupling)

Step 1: Define Engine


@Component
public class Engine {
public void start() {
System.out.println("Engine started...");
}
}

Step 2: Car Class with DI


@Component
public class Car {
private final Engine engine;

5
Spring Framework

@Autowired // Spring injects Engine automatically


public Car(Engine engine) {
this.engine = engine;
}

public void drive() {


engine.start();
System.out.println("Car is moving...");
}
}

Step 3: Spring Boot main Class


@SpringBootApplication
public class MyApp implements CommandLineRunner {

@Autowired
private Car car;

public static void main(String[] args) {


SpringApplication.run(MyApp.class, args);
}

@Override
public void run(String... args) {
car.drive();
}
}

Internal Working of Spring IoC

1. Spring scans for @Component classes.


2. Spring creates the bean instances.
3. Spring injects dependencies using @Autowired.
4. Spring manages the lifecycle of these beans.

Spring IoC provides two major IoC Container

1. Bean Factory – Lightweight, lazy initialization


2. ApplicationContext – Full featured, used in most cases

AOP – Aspect Oriented Programming in Spring


Aspect-Oriented Programming (AOP) is a programming paradigm that allows you to modularize cross-
cutting concerns like: Logging, Security, Transactions, Caching
These are aspects of an application that affect multiple classes, but should not clutter core business
logic.
6
Spring Framework
Without AOP, you'd repeat the same code (e.g., logging or security) in many places — leading to code
duplication and tight coupling. With AOP, you can define such behavior in one place, and apply it
declaratively.

Core AOP Concepts in Spring


• Aspect – a class that defines cross-cutting concerns
• Join Point – a point in the execution of program (e.g. method call)
• Advice – action taken at a join point (before, after, around)
• Pointcut – expression that matches join points
• Weaving – linking aspects to other application objects

Example Logging with AOP

Step 1: add Spring AOP Dependency

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Step 2: Business Service


@Service
public class PaymentService {
public void makePayment(String user, double amount) {
System.out.println("Processing payment of ₹" + amount + " for user: " + user);
}
}

Step 3: Create Logging Aspect


@Aspect
@Component
public class LoggingAspect {

// This is the pointcut expression for all methods in PaymentService


@Before("execution(* com.example.demo.PaymentService.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("LOG: Method called: " + joinPoint.getSignature().getName());
}

@After("execution(* com.example.demo.PaymentService.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("LOG: Method finished: " +
joinPoint.getSignature().getName());
}
}

7
Spring Framework

Step 4: Run from Main


@SpringBootApplication
public class MyApp implements CommandLineRunner {

@Autowired
private PaymentService paymentService;

public static void main(String[] args) {


SpringApplication.run(MyApp.class, args);
}

@Override
public void run(String... args) {
paymentService.makePayment("Dhaneshwar", 2500);
}
}

Output

Types of Advice

Annotation Working
@Before Before method execution
@After After method finishes
@AfterReturning After successful method completion
@AfterThrowing After method throws an exception
@Around Before and after method execution
Benefits of AOP in Spring Boot:

• Improved Modularity: Separates cross-cutting concerns from business logic, leading to cleaner
and more focused code.

• Enhanced Reusability: Aspects can be reused across different parts of the application or even in
other projects.

• Centralized Management: Allows centralized management of common functionalities like logging


or security policies.

• Reduced Code Duplication: Avoids scattering the same logic throughout multiple classes.

8
Spring Framework
Spring Beans and their Scopes
A spring bean is an object that is

• Managed by the Spring IoC container


• Created, configured and wired automatically
• Defined using annotations like @Component, @Service or XML configuration

In short, A Spring Bean is just a Java Object whose lifecycle is managed by Spring.

Example Simple Bean

@Component
public class MyService {
public void serve() {
System.out.println("Service is running...");
}
}

Spring provides five core bean scopes (for Spring Framwork, Spring Boot uses primarily the first two)

1. Singleton – ( default ) One shared instance per Spring container


2. Prototype – a new instance every time it’s requested
3. Request – one instance per HTTP request (web apps only)
4. Session – one instance per HTTP session (web apps only)
5. Application – one instance per ServletContext (web apps only)

Example

@Component @Component
@Scope("singleton") // Optional – default @Scope("prototype")
public class SingletonBean { public class PrototypeBean {
public SingletonBean() { public PrototypeBean() {
System.out.println("Singleton created"); System.out.println("Prototype created");
} }
} }

Runner to test scopes


@SpringBootApplication
public class ScopeApp implements CommandLineRunner {

@Autowired
private ApplicationContext context;

public static void main(String[] args) {


SpringApplication.run(ScopeApp.class, args);

9
Spring Framework
}

@Override
public void run(String... args) {
System.out.println("Requesting SingletonBean twice:");
context.getBean(SingletonBean.class);
context.getBean(SingletonBean.class);

System.out.println("Requesting PrototypeBean twice:");


context.getBean(PrototypeBean.class);
context.getBean(PrototypeBean.class);
}
}

Spring Bean Life Cycle Callbacks


Spring provides lifecycle callback mechanisms that allow you to:
• Run custom logic after a bean is created and initialized
• Clean up resources before a bean is destroyed
This is useful for initializing connections, loading configurations, releasing resources, etc.

Life Cycle Phases


1. Instantiation – Spring creates the bean instance.
2. Populate Properties – Dependencies are injected.
3. Initialization – Custom logic can run here.
4. Destruction – Clean-up logic is executed before the bean is destroyed (only for singleton beans).

Methods to define lifecycle Callbacks


• @PostConstruct – run after dependencies are injected
• @PreDestroy – run before the bean is removed
• InitializationBean – Interface method afterPropertiesSet()
• DisposableBean – Interface method destroy()
• @Bean(initMethod, destroyMethod) – for manual Java config

Example using @PostConstruct and @PreDestroy


import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.stereotype.Component;

10
Spring Framework

@Component
public class MyBean {

public MyBean() {
System.out.println("Constructor: Bean is being created");
}

@PostConstruct
public void init() {
System.out.println("PostConstruct: Bean is initialized");
}

@PreDestroy
public void destroy() {
System.out.println("PreDestroy: Bean is about to be destroyed");
}
}

Runner Application
@SpringBootApplication
public class LifecycleApp {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(LifecycleApp.class, args);
context.close(); // Trigger @PreDestroy
}
}

Bean Configuration Styles


Spring offers multiple ways to define and configure beans, giving developers flexibility based on their
application structure and preferences.

1. XML Based configuration (Legacy Style) – traditional way to define beans in


applicationContext.xml. this styles advantages as clear separation of configuration and logic,
Useful for XML-heavy legacy systems.
<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

11
Spring Framework
<bean id="myBean" class="com.example.MyBean"/>
</beans>

2. Annotation based configuration – Spring uses annotations like @Component, @Service,


@Repository, and @Controller to define beans. Advantages cleaner and easier to manage,
reduces XML biolerplate
@Component
public class MyBean {
public void show() {
System.out.println("Hello from MyBean");
}
}

We also need to enable component scanning:


@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

3. Java Based configuration (JavaConfig) – introduced in Spring 3, allows defining beans using Java
classes and the @Bean annotations. Advantages – type safe, leverages Java language features,
easier to debug and refactor
4. Spring Boot Auto-Configuration – based on the dependencies in our pom.xml or build.gradle,
reducing the need for explicit configuration. Advantages – Minimal configuration, Great for rapid
development.

Spring boot Build System


In Spring Boot, the build system refers to the tools and configurations used to:
• Manage project dependencies
• Compile and package the application
• Run, test, and deploy the application
Spring Boot supports major build tools like:
1. Maven (Apache Maven) – a powerful project management and build automation tool using
pom.xml
Example pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<parent>

12
Spring Framework
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Commands
mvn clean install – Build the project
mvn spring-boot:run – Run Spring Boot app
2. Gradle – A flexible and faster build tool using build.gradle or build.gradle.kts
Example : build.gradle
plugins {
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.0'
id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
useJUnitPlatform()
}

13
Spring Framework

Spring Boot Code Structure


Spring Boot follows a convention-over-configuration approach, so it has a standard, organized directory
structure that makes development easier and faster.

Typical Spring Boot Project Structure

Component Roles

• Controller – REST APIs or web controllers


• Service – Business logic layer
• Repository – data access layer (JPA, JDBC)
• Model – Java classes (Entities , DTOs)
• Resources – config, templates , static files

14
Spring Framework
Example

DemoApplication.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

HelloController.java
package com.example.demo.controller;

import com.example.demo.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class HelloController {

@Autowired
private HelloService helloService;

@GetMapping("/hello")
public String sayHello() {
return helloService.getGreeting();
}
}

HelloService.java
package com.example.demo.service;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
public String getGreeting() {
return "Hello from Spring Boot!";
}
}

15
Spring Framework
Spring Boot Runners
In Spring Boot, runners are special interfaces that allow you to run specific code just after the Spring
application context has been loaded and the application has started.

Types of Runners
1. CommandLineRunner – executes code after application starts up, with access to command line
args
2. ApplicationRunner – Similar to CommandLineRunner, but gives access to parsed
ApplicationArguments

Example : CommandLineRunner
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyCommandLineRunner implements CommandLineRunner {

@Override
public void run(String... args) {
System.out.println("CommandLineRunner running...");
for (String arg : args) {
System.out.println("Arg: " + arg);
}
}
}
Use Cases of CommandLineRunner
• Initializing data
• Running background processes
• Logging startup diagnostics

Example: ApplicationRunner
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationRunner implements ApplicationRunner {

@Override
public void run(ApplicationArguments args) {
System.out.println("ApplicationRunner running...");
System.out.println("Option names: " + args.getOptionNames());
}
}

16
Spring Framework
Spring Boot Logger
Logging is essential in any application to trace execution, debug issues, and monitor performance.
Spring Boot provides built-in support for logging using common logging frameworks like:
• SLF4J (Simple Logging Facade for Java) - Spring Boot uses SLF4J for abstraction and Logback as
the default logging implementation.
• Logback (default)
• Log4j2 (optional)
• Java Util Logging (JUL)
Example
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class MyLoggerExample {

private static final Logger logger = LoggerFactory.getLogger(MyLoggerExample.class);

public void processTask() {


logger.info("INFO: Task processing started...");
logger.debug("DEBUG: Debugging info here");
logger.warn("WARN: Warning message");
logger.error("ERROR: An error occurred");
}
}

Log Level – TRACE, DEBUG, INFO(default), WARN, ERROR, OFF


The log level can be changed from application.properties file

# Set global log level

logging.level.root=INFO

# Set log level for a specific package/class

logging.level.com.example.demo=DEBUG

Building RESTful Web Service


Spring Boot makes it simple to create production-grade REST (Representational State Transfer) APIs with
minimal configuration. A RESTful Web Service exposes HTTP endpoints (like GET, POST, PUT, DELETE) to
perform CRUD operations on resources (like a user, product, etc.).

17
Spring Framework
Project Structure

model.User class
package com.cs2e.user.model;

public class User {


private int id;
private String name;
private String email;

public User() {
}

public User(int id, String name, String email) {


this.id = id;
this.name = name;
this.email = email;
}

// Getters and Setters


}

UserService.java
package com.cs2e.user.service;

import com.cs2e.user.model.User;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class UserService {
private final Map<Integer, User> userMap = new HashMap<>();

public List<User> getAllUsers() {


return new ArrayList<>(userMap.values());
}

public User getUserById(int id) {


18
Spring Framework
return userMap.get(id);
}

public User addUser(User user) {


userMap.put(user.getId(), user);
return user;
}

public void deleteUser(int id) {


userMap.remove(id);
}
}

UserController.java
package com.cs2e.user.controller;

import com.cs2e.user.model.User;
import com.cs2e.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

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

@Autowired
private UserService userService;

@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}

@GetMapping("/{id}")
public User getUser(@PathVariable int id) {
return userService.getUserById(id);
}

@PostMapping
public User createUser(@RequestBody User user) {
return userService.addUser(user);
}

@DeleteMapping("/{id}")
public String deleteUser(@PathVariable int id) {
userService.deleteUser(id);
return "User deleted with id: " + id;
}
}
19
Spring Framework

UserApplication.java
package com.cs2e.user;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}

@RestController - A specialized version of @Controller. Marks the class as a web controller and ensures
all return values are automatically serialized as JSON or XML.

@RequestMapping - Used to map HTTP requests to handler methods or classes. Can be used at the
class level (base path) or method level.

@RequestBody - Used to bind the HTTP request body to a Java object. Commonly used with POST, PUT,
or PATCH methods.

@PathVariable - Extracts values from the URI path.

@RequestParam - Used to extract query parameters from the request.

20

You might also like