Spring Framework Unit 5
Spring Framework Unit 5
Spring Framework
Spring is a lightweight and popular open-source Java-based framework developed by
Rod Johnson in 2003. It is used to develop enterprise-level applications.. Its core
features can be used by any Java application, but there are extensions for building
web applications on top of the Java EE (Enterprise Edition) platform. Spring is known
for its modularity, which means you can use only the parts you need without the
overhead of the entire framework.
Advantages of Spring Framework
1. Modular and Lightweight: Spring follows a modular architecture, allowing
developers to use only the components they need, making application more
lightweight and easier to maintain. This modularity also promotes better code
organization.
2. Flexible Configuration: Spring supports multiple configuration options,
including XML , java-based configuration and annotation based configuration
this flexibility allow developers to choose the most suitable code approach for
their projects.
3. Dependency Injection (DI): Spring supports Dependency Injection which
simplifies the management of component dependencies, making code more
testable and adaptable to changes.
4. Aspect oriented programming (AOP): Spring provides AOP Support allowing,
developers to separate cross-cutting concern like logging, security and
transaction from the core application logic. This improves code modularity and
maintainability.
5. Simplified Database Access: Spring JDBC and Object Relation Mapping (ORM)
support (e.g. Hibernate, JPA) simplifies database access, reduce boilerplate
code and improves data access efficiency.
6. Testing support: Spring architecture encourages writing unit tests and it
provide support for integration testing.
7. Security: Spring security provides a robust framework for implementing
authentication and authorization, making it easier to secure web application
and services.
8. Integration Capabilities: Spring provides Integration with various technologies
and framework, such as angular, react, messaging systems (JMS), web services
(SOAP and REST), and other third-party libraries and APIs.
9. Scalability: Spring applications can be designed for scalability and can easily
integrate with cloud-native technologies and microservices architecture.
10. Open Source: Spring is open-source, which means it’s free to use and can be
customized to meet specific project requirements.
Spring container
The Spring container is at the core of the Spring Framework. The container will create
the objects, wire them together, configure them, and manage their complete life
cycle from creation till destruction. It utilizes dependency injection (DI) to provide
loose coupling between objects and to promote easier testing and maintenance. The
Spring Container, also known as the Inversion of Control (IoC) container, is what
makes the Spring Framework so powerful and flexible.
The container gets its instructions on what objects to instantiate, configure, and
assemble by reading the configuration metadata provided. The configuration
metadata can be represented either by XML, Java annotations, or Java code. The
following diagram represents a high-level view of how Spring works. The Spring IoC
container makes use of Java POJO classes and configuration metadata to produce a
fully configured and executable system or application.
There are 2 types of IoC containers:
1. BeanFactory: BeanFactory holds bean definitions and instantiates them
whenever asked for by the client application
2. ApplicationContext: This the most powerful Container, compare to Bean-
factory
configurableApplicationContext: It is use in spring boot. One of the implementation
of the ApplicationContext container. This container is used for Event Handling
propose
That means if you want to use an IoC container in spring whether we need to use a
BeanFactory or ApplicationContext or configurableApplicationContext. The
BeanFactory is the most basic version of IoC containers, and the ApplicationContext
extends the features of BeanFactory.
Example:
Step 1: Create a POJO (Student.java)
package Bean;
public class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void display() {
System.out.println("Name: "+name);
System.out.println("Id: "+id);
}}
Step 2: Create a Spring Configuration File (applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- bean definitions here -->
<bean class="Bean.Student" id="stdId">
<property name="id" value="101"></property>
<property name="name" value="priya"></property> </bean>
<bean class="Bean.Student" id="stdId1">
<property name="id" value="102"></property>
<property name="name" value="Pinki"></property> </bean> </beans>
Step 3: Write the Main Application to Connect Everything (TestMain.java)
//spring-beans .jar
//spring-core .jar
//spring-context .jar
//commons-logging .jar
//spring-expression .jar
Download above mentioned jar file
package main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import Bean.Student;
public class TestMain {
public static void main(String[] args) {
String config_loc= "/spResources/applicationContext.xml";
ApplicationContext context = new
ClassPathXmlApplicationContext(config_loc);
Student s = (Student)context.getBean("stdId");
s.display();
Student s1 = (Student)context.getBean("stdId1");
s1.display(); }}
Output:
Name: priya
Id: 101
Name: Pinki
Id: 102
Using java Based Configuration
Step 1. create POJO class (Student.java)
Step2. create SpringConfigFile (Springconfig.java)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import Beans.Student;
@Configuration
public class SpringConfig {
@Bean("stdId1")
public Student createStudentObj(){
Student std = new Student();
std.setId(101);
std.setName("priya");
return std; }}
Step 3: Write the Main Application to Connect Everything (TestMain.java)
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.
AnnotationConfigApplicationContext;
import Beans.Student;
import Resourcess.SpringConfig;
public class TestMain {
public static void main(String[] args) {
ApplicationContext context = new
AnnotationConfigApplicationContext(SpringConfig.class);
Student std = (Student)context.getBean("stdId1");
std.display(); }}
Using Annotation Based Configuration
Step 1 create POJO class(Employee.java)
package Beans;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Employee {
@Value("101")
int empId;
@Value("poojaa")
String empName;
public int getEmpId() {
return empId; }
public void setEmpId(int empId) {
this.empId = empId; }
public String getEmpName() {
return empName; }
public void setEmpName(String empName) {
this.empName = empName; }
public void display() {
System.out.println("Name: "+empName);
System.out.println("Id: "+empId); }}
Step2. Create xml config file (applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- bean definitions here -->
<context:component-scan base-package="Beans" /> </beans>
Step 3: Write the Main Application to Connect Everything (EmpMain.java)
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import Beans.Employee;
public class EmpMain {
public static void main(String[] args) {
String srcFile = "/Resourcess/applicationContext.xml";
ApplicationContext context = new
ClassPathXmlApplicationContext(srcFile);
Employee e = (Employee) context.getBean("employee");
e.display();
}}
Aspect-Oriented Programming (AOP)
Aspect-Oriented Programming (AOP) is a programming paradigm that aims to
increase modularity by allowing the separation of cross-cutting concerns. These
concerns are aspects of a program that affect other parts of the program and
often include functionalities like logging, security, and transaction management,
which cut across multiple modules of an application.
Examples of AOP Use:
Logging: Automatically logging method calls and their parameters without
modifyinSg the method's code.
Security: Implementing access control checks across various modules.
Transaction Management: Managing transactions declaratively without hard-
coding transactional code into business logic.
Key Concepts of AOP:
Aspect: An aspect is a modularization of a concern that cuts across multiple classes.
Advice: Represent an action taken by an aspect at particular join point.
Join Point: Join Point is any point in your program such as method execution,
exception handling, field access etc. Spring supports only method execution join
point.
Pointcut: It is an expression of AOP that matches join point.
//AspectJ Runtime , AspectJ Weaver Jar file Required
Example
public interface Payment {
public void makePayment(); }
public class PaymentImpl implements Payment{
public void makePayment() {
System.out.println("Amount Debited.......");
System.out.println("Amount credited......."); }}
Configuration File
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- bean definitions here -->
<aop:aspectj-autoproxy />
<context:component-scan base-package="Beans" />
<bean name="pmnt" class="main.PaymentImpl" />
<bean name="myAspect" class="main.MyPaymentAspect" />
</beans>
MyPaymentAspect.java (Class)
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyPaymentAspect {
@Before("execution(* main.PaymentImpl.makePayment())")
public void printBefore() {
System.out.println("Payment Started----");
}}
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.
AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestPayment {
public static void main(String[] args) {
String srcFile = "/Resourcess/applicationContext.xml";
ApplicationContext context = new
ClassPathXmlApplicationContext(srcFile);
Payment p = context.getBean("pmnt" , Payment.class);
p.makePayment(); }}
Bean Scopes
Bean scopes define the lifecycle and visibility of the beans within the container. The
scope of a bean determines how and when the bean is instantiated and how long it
lives within the application. The primary bean scopes in Spring include singleton,
prototype, request, session.
Singleton Scope: This is the default scope in Spring. A single instance of the bean is
created per Spring IoC container.
• Only one instance is shared across the application.
• The bean is instantiated during the container startup by default.
• Suitable for stateless, shared resources such as services or DAOs.
Prototype Scope: A new instance of the bean is created every time it is requested
from the Spring container.
• Multiple instances are created.
• Suitable for stateful beans or those that maintain internal state.
Eg: @Scope("prototype")
Request Scope: A new bean instance is created for each HTTP request. This scope is
only valid in the context of a web-aware Spring Application Context.
• The bean is alive during the duration of an HTTP request.
• Useful for request-scoped data in web applications.
@Scope("request")
Session Scope: A single bean instance is created for the lifecycle of an HTTP session.
This scope is valid in a web application context.
• The bean lives as long as the HTTP session.
• Suitable for storing user session data across multiple requests.
@Scope("session")
Application Scope: in the Spring Framework is a context scope that is primarily used
in web applications. It ensures that a bean is scoped to the lifecycle of the
ServletContext, which means that a single instance of the bean will be created and
shared across the entire application.
• A single instance of the bean is created for the entire web application.
• The bean is shared among all users and all HTTP requests throughout the
application's lifetime.
• The bean's lifecycle is tied to the ServletContext.
• It gets instantiated when the web application starts and is destroyed when the
web application is shut down.
@Scope("application")
WebSocket scope: WebSocket scope in Spring is a specialized scope that manages
the lifecycle of a bean to match the lifecycle of a WebSocket session. This scope is
particularly useful in applications that use WebSocket for real-time communication
between clients and servers, such as chat applications, live updates, or interactive
games.
• Single Instance per WebSocket Session: A new bean instance is created for
each WebSocket session.
• Lifecycle: The bean is created when a WebSocket session is established and
destroyed when the session ends.
• State Management: Suitable for managing state and data specific to a
particular WebSocket session.
Dependency Injection (DI)
Dependency Injection is a design pattern used to implement Inversion of Control
(IoC), allowing the creation of dependent objects outside of a class and providing
those objects to a class in various ways. It helps in creating loosely coupled code,
improving code maintainability and testability.
Types of Spring Dependency Injection:
Setter Dependency Injection (SDI): This is the simpler of the two DI methods. In this,
the DI will be injected with the help of setter and/or getter methods. Now to set the
DI as SDI in the bean, it is done through the bean-configuration file For this, the
property to be set with the SDI is declared under the <property> tag in the bean-
config file.
1. Create the Address Class
public class Address {
private String street;
private String city;
private String zipCode;
// Getters and Setters
public String getStreet() {
return street }
public void setStreet(String street) {
this.street = street; }
public String getCity() {
return city; }
public void setCity(String city) {
this.city = city; }
public String getZipCode() {
return zipCode; }
public void setZipCode(String zipCode) {
this.zipCode = zipCode; }
public String toString() {
return street + ", " + city + ", " + zipCode;
}}
2. Create the Student Class
public class Student {
private int id;
private String name;
private Address address;
// Getters and Setters
public int getId() {
return id;
public void setId(int id) {
this.id = id;}
public String getName() {
return name; }
public void setName(String name) {
this.name = name; }
public Address getAddress() {
return address; }
public void setAddress(Address address) {
this.address = address; }
public String toString() {
return "Student [id=" + id + ", name=" + name + ", address=" + address + "]";}}
3. Create the XML Configuration File
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- Definition for Address bean -->
<bean id="addressBean" class="com.example.Address">
<property name="street" value="123 Main St"/>
<property name="city" value="Springfield"/>
<property name="zipCode" value="12345"/>
</bean>
<!-- Definition for Student bean -->
<bean id="studentBean" class="com.example.Student">
<property name="id" value="1"/>
<property name="name" value="John Doe"/>
<property name="address" ref="addressBean"/>
</bean>
</beans>
4. Create the Main Class to Load the ApplicationContext
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("studentBean");
System.out.println(student);
}}
Constructor Dependency Injection involves providing the required dependencies
to a class through its constructor. When an instance of the class is created, all
dependencies are injected via the constructor. This approach ensures that the
dependencies are available immediately upon object creation, promoting
immutability.
To use Constructor Dependency Injection (DI) instead of Setter DI, you need to
modify the Student and Address classes to include constructors that take the
required dependencies as parameters. You also need to update the XML
configuration file to use the constructor-arg elements for DI.
Example:
1. Create Parameterized Constructors in both class Student and Address (above
example )
2. Update XML file
<?xml version="1.0" encoding="UTF-8"?>
<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">
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("Application started with ApplicationRunner");
}}
Logger in Spring Boot
Logging in Spring Boot is typically done using the SLF4J (Simple Logging Facade
for Java) API along with a logging backend like Logback, Log4j2, or Java Util
Logging. Spring Boot provides built-in support for logging, and you can use the
Logger interface to log messages at different levels (INFO, DEBUG, ERROR,
etc.).
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
public void myMethod() {
logger.info("This is an info message");
logger.debug("This is a debug message");
logger.error("This is an error message");
}
# application.properties (Configure this in application.properties file)
logging.level.org.springframework=INFO
logging.level.com.example=DEBUG
logging.file.name=logs/myapp.log
@Component
@Entity
@Table
public class Employee{
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private int id;
private String name;
//setter getter
// to String}
5. Create the Repository
import com.example.demo.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee,
Integer> {
}
6. Create the Service
import com.example.demo.entity.Employee;
import com.example.demo.exception.ResourceNotFoundException;
import com.example.demo.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
@PutMapping("/{id}")
public Employee updateEmployee(@PathVariable int id, @RequestBody
Employee employeeDetails) {
Employee employee = employeeService.getEmployeeById(id);
employee.setName(employeeDetails.getName());