Introduction to Spring
The Spring framework is an open-source Java application framework, which is based on two
key principles:
1. dependency injection
2. Inversion of Control.
Spring has the ability to autowire the dependency at run time, which allows the developer
to write loosely coupled code.
Spring framework uses metadata in the form of xml file or java annotations to create objects
and identifies dependencies, thereby producing a ready-to-use application.
What are dependencies?
A typical web application is divided into three layers:
(1) Web Layer
(2) Business Layer
(3) data Layer
These layers have objects that collaborate with each other to make the application
work.
These collaborations are called dependencies.
A typical application has a lot of classes and dependencies
What is Tight Coupling and Loosely Coupling?
Tightly coupled code involves creating an instance of the dependency inside the class
Class A
{
void print( )
{
[Link](“Welcome to KLU”);
}
}
Class Main
{
A a=new A( );
[Link]()
Loose coupling : In simple words, loose coupling means java classes are mostly
independent.
Interface I
{
void print( );
}
Class B implements I
{
void print( )
{
[Link](“Welcome to CSE”);
}
}
Class Main
{
I i= new B();
[Link]();
}
Spring Dependency Injection (DI) is a good choice. Spring can make loosely coupling through
Dependency Injection.
Spring Framework: Features and Advantages
Features:
Create a Java method that runs in a database transaction with no help from
transaction APIs.
Create a local Java method that defines a remote procedure with no help from
remote APIs.
Create a local Java method for a management operation with no help from JMX APIs.
Create a local Java method for a message handler with no help from JMS APIs.
Spring is a lightweight framework. It provides the best mechanisms for different
frameworks, such as Struts, Hibernate, EJB, JSF, and Tapestry.
It helps solve real-time technical problems. Spring contains multiple modules, such
as WEB MVC(Model-View-Controller), IOC(inversion of control), DAO(data access
object), AOP(Aspect-Oriented Programming), Context, and ORM (Object–relational
mapping
.
Spring also helps create scalable, secure, and robust business-based web
applications.
We can consider the Spring framework a cluster of sub frameworks such as Spring
Web Flow, Spring ORM, and Spring MVC.
Advantages:
Pre-defined Templates
Loose Coupling
Easy and Simple to Test
Non-invasive
Fast Development
Strong Abstraction Support
Spring's Web Framework is Well-Organized
Spring Delivers a Suitable API
Lightweight IoC
Constant Transaction Management
Important Terminologies
Beans
Autowiring
Dependency injection
Inversion of Control
IoC container
Bean factory
Application context
Beans
Beans are the objects of classes that are managed by Spring. Traditionally, objects used to
create their own dependencies, but Spring manages all the dependencies of an object and
instantiates the object after injecting the required dependencies.
The @Component annotation is the most common method of defining beans.
@Component
public
class
Vehicle
{
}
Autowiring:
The process of identifying a dependency, looking for a match, andthen populating the
dependency is called autowiring. The @Autowired annotation tells Spring to find and inject
acollaborating bean into another.
Dependency injection
Dependency injection is the process by which Spring looks up the beans that are needed for
a particular bean to function and injects them as a dependency. Spring can perform
dependency injection by using constructor or by using a setter method.
Inversion of Control
Traditionally, the class which needed dependency created an instance of dependency. The
class decided when to create dependency and how to create it.
Inversion of Control (IoC) in Spring is a design principle where the framework, not your
code, manages object creation, configuration, and lifecycle, inverting the traditional flow
where your code controls these aspects
IoC container
An IoC container is a framework that provides the Inversion of Control functionality. IoC
containers are a generic term. It is not framework specific. Spring offers two
implementations of the IoC container:
1) Bean factory
2) Application context
Bean factory
The basic version of the Spring IoC container is bean factory. It is the legacy IoC
container and provides basic management for beans and wiring of dependencies. In
Spring, bean factory still exists to provide backward compatibility.
Application context
Application context adds more features to the bean factory that are typically needed by an
enterprise application. It is the most important part of the Spring framework. All the core
logic of Spring happens here. It includes basic management of beans and wiring
dependencies as provided by the bean factory.
Spring Framework Architecture and Modules
Spring takes control of populating dependencies and injects the one object into another
object. Spring is a dependency injection framework that promotes loosely coupled code.
Spring inverts the control by taking responsibility for populating the dependency. This is
referred to as Inversion of Control (IoC).
Spring modules
Data access/ integration
Web (MVC/remoting)
Test
AOP
Spring Projects
The Core Container contains the following modules: Beans, Core, Context, and Spring
Expression Language (SpEL). These modules provide fundamental functionality of the Spring
framework, like Inversion of Control (IoC), dependency injection, internationalization as well
as support for querying the object at runtime.
Data access/ integration
Spring has very good integration with data and integration layers, and provides support to
interact with databases. It contains modules like JDBC, ORM, OXM, JMS, and Transactions.
Web (MVC/remoting)
It contains the Web, Servlets, Portlets, and Sockets modules to support the creation of a
web application. Spring offers a web framework of its own called Spring MVC.
Spring projects
1. Spring Boot: is used to develop micro services. It makes developing applications easy
through features like startup projects, autoconfiguration, and actuator. Spring Boot
has gained massive popularity since it was first released in 2014.
2. Spring Cloud: allows the development of cloud native applications that can be
dynamically configured and deployed. It provides functionality for handling common
patterns in distributed systems.
3. Spring Data: provides consistent access to SQL and NoSQL databases.
4. Spring Integration: implements the patterns outlined by the book Enterprise
Application Integration Patterns It allows enterprise applications to be connected
easily through messaging and declarative adapters.
5. Spring Batch: provides functionality to handle large volumes of datalike ability to
restart, ability to read from and write to different systems, chunk processing, parallel
processing, and transaction management.
6. Spring Security: provides security solutions for different applications be it a web
application or a REST service. It also provides authentication and authorization
features.
7. Spring Session: manages session information and makes it easier to share session
data between services in the cloud regardless of the platform/container. It also
supports multiple sessions in a single browser instance.
8. Spring Mobile: offers device detection and progressive rendering options that make
mobile web application development easy.
9. Spring Android: facilitates the development of Android applications.
Important terminologies in depth
Bean
A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC
container. These beans are created with the configuration metadata that you supply to the
container.
Beans are the objects of classes that are managed by Spring. Traditionally, objects used to
create their own dependencies, but Spring manages all the dependencies of an object and
instantiates the object after injecting the required dependencies.
Spring - Bean Definition
class
name
scope
constructor-arg
properties
autowiring mode
lazy-initialization mode
There are 3 ways to configure spring Bean:
1. XML based configuration file.
2. Annotation-based configuration
3. Java-based configuration
XML based Bean Configuration Example
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "[Link]
xmlns:xsi = "[Link]
xsi:schemaLocation = "[Link]
[Link]
<!-- A simple bean definition -->
<bean id = "..." class = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with lazy init set on -->
<bean id = "..." class = "..." lazy-init = "true">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with initialization method -->
<bean id = "..." class = "..." init-method = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with destruction method -->
<bean id = "..." class = "..." destroy-method = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
[Link]
public class HelloKlu {
private String message;
public void setMessage(String message){
[Link] = message;
}
public void getMessage(){
[Link]("Your Message : " + message);
}
[Link]
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "[Link]
xmlns:xsi = "[Link]
xsi:schemaLocation = "[Link]
[Link]
<bean id = "helloklu" class = "[Link]">
<property name = "message" value = "Hello K L University!"/>
</bean>
</beans>
[Link]
import [Link];
import [Link];
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("[Link]");
HelloKlu obj = (HelloKlu) [Link]("helloklu");
[Link]();
}
}
Annotation based Bean Configuration Example
@Component
@Autowired
@Qualifier
JSR-250 Annotations
[Link]
@Component
public class HelloKlu {
private String message;
public void setMessage(String message){
[Link] = message;
}
public void getMessage(){
[Link]("Your Message : " + message);
}
[Link]
import [Link];
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
[Link]("[Link]");
[Link]();
HelloKlu ms = [Link]([Link]);
[Link]("Hello K L University");
[Link]()
[Link](); }
}
Java Based Bean Configuration Example
@Configuration & @Bean Annotations:
Annotating a class with the @Configuration indicates that the class can be used by
the Spring IoC container as a source of bean definitions.
The @Bean annotation tells Spring that a method annotated with @Bean will return
an object that should be registered as a bean in the Spring application context.
[Link]
public class HelloKlu {
private String message;
public void setMessage(String message){
[Link] = message;
}
public void getMessage(){
[Link]("Your Message : " + message);
}
[Link]
import [Link].*;
@Configuration
public class HelloKluConfig {
@Bean
public HelloKlu helloKlu(){
return new HelloKlu();
}
}
[Link]
import [Link];
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext([Link]);
HelloWorld helloWorld = [Link]([Link]);
[Link]("Hello World!");
[Link]();
}
}
Spring Bean Scopes
When defining a <bean> you have the option of declaring a scope for that bean.
There are five types of spring bean scopes:
1. singleton - only one instance of the spring bean will be created for the spring container.
This is the default spring bean scope. While using this scope, make sure bean doesn’t
have shared instance variables otherwise it might lead to data inconsistency issues.
2. prototype – A new instance will be created every time the bean is requested from the
spring container.
3. request – This is same as prototype scope; however it’s meant to be used for web
applications. A new instance of the bean will be created for each HTTP request.
4. session – A new bean will be created for each HTTP session by the container.
5. global-session – This is used to create global session beans for Portlet applications.
Inversion of Control
Traditionally, the class which needed the dependency created an instance of the
dependency. The class decided when to create the dependency and how to create it. For
example, Engine class is a dependency of Vehicle class, which creates its object.
The Spring container uses DI to manage the components that make up an application.
These objects are called Spring Beans.
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.
IoC container
An IoC container is a framework that provides the Inversion of Control functionality.
IoC container is a generic term. It is not framework specific.
Spring offers two implementations of the IoC container:
o Bean factory
o Application context
Spring Bean factory
The basic version of the Spring IoC container is bean factory. It is the legacy IoC container
and provides basic management for beans and wiring of dependencies. In Spring, bean
factory still exists to provide backward compatibility.
[Link]
public class HelloKlu {
private String message;
public void setMessage(String message){
[Link] = message;
}
public void getMessage(){
[Link]("Your Message : " + message);
}
[Link]
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "[Link]
xmlns:xsi = "[Link]
xsi:schemaLocation = "[Link]
[Link]
<bean id = "helloklu" class = "[Link]">
<property name = "message" value = "Hello K L University!"/>
</bean>
</beans>
[Link]
import [Link];
import [Link];
public class App {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("[Link]"));
HelloKlu obj = (HelloKlu) [Link]("helloklu");
[Link]();
}
}
Spring ApplicationContext Container
Application context adds more features to the bean factory that are typically needed by an
enterprise application. It is the most important part of the Spring framework. All the core
logic of Spring happens here. It includes basic management of beans and wiring of
dependencies as provided by the bean factory. Additional features in application context
include Spring AOP features, internationalization, web application context, etc.
Types of ApplicationContext
1. AnnotationConfigApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext([Link])
AccountService as = [Link]([Link]);
2. FileSystemXMLApplicationContext
ApplicationContext context = new FileSystemXmlApplicationContext(path);
AccountService accountService = [Link]("accountService", [Link]);
3. ClassPathXmlApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("[Link]");
AccountService accountService = [Link]("accountService", [Link]);
4. AnnotationConfigWebApplicationContext
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
[Link]([Link]);
[Link](container);
5. XmlWebApplicationContext
XmlWebApplicationContext context = new XmlWebApplicationContext();
[Link]("/WEB-INF/spring/[Link]");
[Link](container);
Dependency injection
Dependency injection is the process by which Spring looks up the beans that are needed for
a particular bean to function and injects them as a dependency. Spring can perform
dependency injection by following:
1. Setter DI
2. Constructor DI
3. Interface DI
SetterDI:
In setter dependency injection, the Spring IOC container injects a component’s
dependencies via JavaBean-style Setter methods. A component’s setters expose the
dependencies the IoC container can manage.
As the name implies, using setter method spring container will inject the dependencies. This
technique is considered as the best approach for dependency injection.
[Link]
----------------
public class Capital {
String capitalName;
public String getCapitalName() {
return capitalName;
}
public void setCapitalName(String capitalName) {
[Link] = capitalName;
}
}
[Link]
-----------------
public class Country {
String countryName;
Capital capital;
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
[Link] = countryName;
}
public Capital getCapital() {
return capital;
}
public void setCapital(Capital capital) {
[Link] = capital;
}
}
[Link]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="[Link]
xmlns:xsi="[Link]
xmlns:aop="[Link]
xsi:schemaLocation="[Link]
[Link]
<bean id="CountryBean" class="country classpath">
<property name="countryName" value="India"/>
<property name="capital" ref="CapitalBean"/>
</bean>
<bean id="CapitalBean" class="Capital classpath">
<property name="capitalName" value="Delhi"/>
</bean>
</beans>
[Link]
---------------------------------
public class SetterInjectionMain {
public static void main(String[] args) {
ApplicationContext appContext = new
ClassPathXmlApplicationContext("[Link]");
Country countryObj = (Country) [Link]("CountryBean");
String countryName=[Link]();
String capitalName=[Link]().getCapitalName();
[Link](capitalName+" is capital of "+countryName);
}
}
Constructor DI
In the case of constructor-based dependency injection, the container will invoke a
constructor with arguments each representing a dependency we want to set.
[Link]
public class Capital {
String capitalName;
public String getCapitalName() {
return capitalName;
}
public void setCapitalName(String capitalName) {
[Link] = capitalName;
}
}
[Link]
-----------------
public class Country {
String countryName;
Capital capital;
public Country(String countryName, Capital capital) {
super();
[Link] = countryName;
[Link] = capital;
}
public String getCountryName() {
return countryName;
}
public Capital getCapital() {
return capital;
}
[Link]
-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="[Link]
xmlns:xsi="[Link]
xmlns:aop="[Link]
xsi:schemaLocation="[Link]
[Link]
<bean id="CountryBean" class="Country classpath">
<constructor-arg index="0" type="[Link]" value="India" />
<constructor-arg index="1" ref="CaptialBean" />
</bean>
<bean id="CaptialBean" class="Capital classpath">
<property name="capitalName" value="Delhi" />
</bean>
</beans>
[Link]
----------------------------
public class ConstructorDIMain{
public static void main(String[] args) {
ApplicationContext appContext = new
ClassPathXmlApplicationContext("[Link]");
Country countryObj = (Country) [Link]("CountryBean");
String countryName=[Link]();
String capitalName=[Link]().getCapitalName();
[Link](capitalName+" is capital of "+countryName);
}}
Interface DI
the dependency provides an injector method that will inject the dependency into any client
passed to it. Clients must implement an interface that exposes a setter method that accepts
the dependency.
It’s not supported by the Spring framework.
Beans Autowiring in spring
Autowiring modes:
There are following autowiring modes which can be used to instruct Spring container to use
autowiring for dependency injection.
no: Default, no auto wiring, set it manually via “ref” attribute as we have done in
dependency injection via setter method post.
byName: Autowiring by property name. Spring container looks at the properties of the
beans on which autowire attribute is set to byName in the XML configuration file and it tries
to match it with name of bean in xml configuration file.
byType: Autowiring by property datatype. Spring container looks at the properties of the
beans on which autowire attribute is set to byType in the XML configuration file. It then tries
to match and wire a property if its type matches with exactly one of the beans name in
configuration file. If more than one such beans exists, a fatal exception is thrown.
There are 2 types of configurations in autowiring
1. XML based configuration
2. Java and Annotation based configuration
Xml Based Autowire
[Link]
---------------
public class Country {
String countryName;
Capital capital;
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
[Link] = countryName;
}
public Capital getCapital() {
return capital;
}
public void setCapital(Capital capital) {
[Link] = capital;
}
}
[Link]
---------------
public class Capital {
String capitalName;
public String getCapitalName() {
return capitalName;
}
public void setCapitalName(String capitalName) {
[Link] = capitalName;
}
}
[Link]
---------------------------------
public class BeanAutowiringByNameMain{
public static void main(String[] args) {
ApplicationContext appContext = new
ClassPathXmlApplicationContext("[Link]");
Country countryObj = (Country) [Link]("country");
String countryName=[Link]();
String capitalName=[Link]().getCapitalName();
[Link](capitalName+" is capital of "+countryName);
}
}
[Link]
-----------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="[Link]
xmlns:xsi="[Link]
xmlns:aop="[Link]
xsi:schemaLocation="[Link]
[Link]
<bean id="country" class="Country class path" autowire="byName">
<property name="countryName" value="India"/>
</bean>
<bean id="capital" class="Capital class path">
<property name="capitalName" value="Delhi" />
</bean>
</beans>
Java and Annotation based configuration
[Link]
public class User {
private int customerId;
private String name;
private String email;
@Autowired
private Address address;
public User() {
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
[Link] = customerId;
}
public String getName() {
return name;
}
public void setName(String name) {
[Link] = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
[Link] = email;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
[Link] = address;
}
}
Address,java
public class Address {
private int houseNo;
private String streetName;
private String city;
private int pin;
public Address() {
}
public Address(int houseNo, String streetName, String city, int pin) {
[Link] = houseNo;
[Link] = streetName;
[Link] = city;
[Link] = pin;
}
public int getHouseNo() {
return houseNo;
}
public void setHouseNo(int houseNo) {
[Link] = houseNo;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
[Link] = streetName;
}
public String getCity() {
return city;
}
public void setCity(String city) {
[Link] = city;
}
public int getPin() {
return pin;
}
public void setPin(int pin) {
[Link] = pin;
}
}
[Link]
public class AppConfig {
@Bean("user")
public User getCustomer()
{
User cust = new User();
[Link](1);
[Link]("Tony");
[Link]("tony@[Link]");
return cust;
}
@Bean
public Address getAddress(){
return new Address(10,"darl street","delhi",110010);
}
[Link]
public class App
{
public static void main( String[] args )
{
AnnotationConfigApplicationContext
annotationConfigApplicationContext =new
AnnotationConfigApplicationContext([Link]);
User user1 = (User)
[Link]("user", [Link]);
[Link]([Link]()+"::"+ [Link]());
[Link]([Link]().getCity());
}
}
Exp1: Create Maven project and convert into Spring application
Exp2: Create Spring project to create XML based bean
Exp3: Create Spring project to create Annotation based bean
Exp4: Create Spring project to create java-based bean
Exp5: Create Spring Application to call Spring Bean Factory
Exp5: Create Spring Application to call Application Context
Exp 5: Create spring project for Dependency Injection using Setter DI
Exp 6: Create spring project for Dependency Injection using Constructor DI
Exp 7: Create spring project for Dependency Injection using Interface DI