Unit - 5 Spring Framework and SpringBoot Sachin Sir
Unit - 5 Spring Framework and SpringBoot Sachin Sir
of Control, AOP, Bean Scopes- Singleton, Prototype, Request, Session, Application, Web
Socket, Auto wiring, Annotations, Life Cycle Call backs, Bean Configuration styles
Spring Boot: Spring Boot Build Systems, Spring Boot Code Structure, Spring Boot Runners,
Logger, BUILDING RESTFUL WEB SERVICES, Rest Controller, Request Mapping, Request
Body, Path Variable, Request Parameter, GET, POST, PUT, DELETE APIs, Build Web
Applications
Spring Framework
Spring is a lightweight framework. It can be thought of as a framework of frameworks because it
provides support to various frameworks such as Struts, Hibernate, Tapestry, EJB, JSF, etc. The
framework, in broader sense, can be defined as a structure where we find solution of the various
technical problems.
The Spring framework comprises several modules such as IOC, AOP, DAO, Context, ORM,
WEB MVC etc. We will learn these modules in next page. Let's understand the IOC and
Dependency Injection first.
Inversion Of Control (IOC) and Dependency Injection
These are the design patterns that are used to remove dependency from the programming code.
They make the code easier to test and maintain. Let's understand this with the following code:
1. class Employee{
2. Address address;
3. Employee(){
4. address=new Address();
5. }
6. }
In such case, there is dependency between the Employee and Address (tight coupling). In the
Inversion of Control scenario, we do this something like this:
1. class Employee{
2. Address address;
3. Employee(Address address){
4. this.address=address;
5. }
6. }
Thus, IOC makes the code loosely coupled. In such case, there is no need to modify the code if
our logic is moved to new environment.
In Spring framework, IOC container is responsible to inject the dependency. We provide
metadata to the IOC container either by XML file or annotation.
Advantage of Dependency Injection
o makes the code loosely coupled so easy to maintain
o makes the code easy to test
Advantages of Spring Framework
There are many advantages of Spring Framework. They are as follows:
1) Predefined Templates
Spring framework provides templates for JDBC, Hibernate, JPA etc. technologies. So there is no
need to write too much code. It hides the basic steps of these technologies.
Let's take the example of JdbcTemplate, you don't need to write the code for exception handling,
creating connection, creating statement, committing transaction, closing connection etc. You
need to write the code of executing query only. Thus, it save a lot of JDBC code.
2) Loose Coupling
The Spring applications are loosely coupled because of dependency injection.
3) Easy to test
The Dependency Injection makes easier to test the application. The EJB or Struts application
require server to run the application but Spring framework doesn't require server.
4) Lightweight
Spring framework is lightweight because of its POJO implementation. The Spring Framework
doesn't force the programmer to inherit any class or implement any interface. That is why it is
said non-invasive.
5) Fast Development
The Dependency Injection feature of Spring Framework and it support to various frameworks
makes the easy development of JavaEE application.
6) Powerful abstraction
It provides powerful abstraction to JavaEE specifications such as JMS, JDBC, JPA and JTA.
7) Declarative support It provides declarative support for caching, validation, transactions and
formatting.
The Dependency Injection is a design pattern that removes the dependency of the programs. In
such case we provide the information from the external source such as XML file. It makes our
code loosely coupled and easier for testing. In such case we write the code as:
1. class Employee{
2. Address address;
3. Employee(Address address){
4. this.address=address;
5. }
6. public void setAddress(Address address){
7. this.address=address;
8. }
9. }
In such case, instance of Address class is provided by external souce such as XML file either by
constructor or setter method.
Two ways to perform Dependency Injection in Spring framework
Spring framework provides two ways to inject dependency
o By Constructor
o By Setter method
Let's see the simple example to inject primitive and string-based values. We have created three
files here:
o Employee.java
o applicationContext.xml
o Test.java
Employee.java
It is a simple class containing two fields id and name. There are four constructors and one
method in this class.
1. package com.javatpoint;
2. public class Employee {
3. private int id;
4. private String name;
5. public Employee() {System.out.println("def cons");}
6. public Employee(int id) {this.id = id;}
7. public Employee(String name) { this.name = name;}
8. public Employee(int id, String name) {
9. this.id = id;
10. this.name = name;
11. }
12. void show(){
13. System.out.println(id+" "+name);
14. }
15. }
1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans
3. xmlns="http://www.springframework.org/schema/beans"
4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5. xmlns:p="http://www.springframework.org/schema/p"
6. xsi:schemaLocation="http://www.springframework.org/schema/beans
7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
8. <bean id="e" class="com.javatpoint.Employee">
9. <constructor-arg value="10" type="int"></constructor-arg>
10. </bean>
11. </beans>
Test.java
This class gets the bean from the applicationContext.xml file and calls the show method.
1. package com.javatpoint;
2. import org.springframework.beans.factory.BeanFactory;
3. import org.springframework.beans.factory.xml.XmlBeanFactory;
4. import org.springframework.core.io.*;
5. public class Test {
6. public static void main(String[] args) {
7. Resource r=new ClassPathResource("applicationContext.xml");
8. BeanFactory factory=new XmlBeanFactory(r);
9. Employee s=(Employee)factory.getBean("e");
10. s.show();
11. }
12. }
Output:10 null
Injecting string-based values
If you don't specify the type attribute in the constructor-arg element, by default string type
constructor will be invoked.
1. ....
2. <bean id="e" class="com.javatpoint.Employee">
3. <constructor-arg value="10"></constructor-arg>
4. </bean>
5. ....
If you change the bean element as given above, string parameter constructor will be invoked and
the output will be 0 10.
Output:0 10
// Class
// Implementing Sim interface
public class Airtel implements Sim {
// Class
// Implementing Sim interface
public class Jio implements Sim{
@Override
public void calling() {
System.out.println("Jio Calling");
}
@Override
public void data() {
System.out.println("Jio Data");
}
}
So let’s now call these methods inside the main method. So by implementing the Run time
polymorphism concept we can do something like this
// Java Program to Illustrate Mobile Class
// Class
public class Mobile {
sim.calling();
sim.data();
}
}
Spring AOP
Aspect Oriented Programming (AOP) compliments OOPs in the sense that it also provides
modularity. But the key unit of modularity is aspect than class.
AOP breaks the program logic into distinct parts (called concerns). It is used to increase
modularity by cross-cutting concerns.
A cross-cutting concern is a concern that can affect the whole application and should be
centralized in one location in code as possible, such as transaction management, authentication,
logging, security etc.
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.
Advice
Advice represents an action taken by an aspect at a particular join point. There are different types
of advices:
o Before Advice: it executes before a join point.
o After Returning Advice: it executes after a joint point completes normally.
o After Throwing Advice: it executes if method exits by throwing an exception.
o After (finally) Advice: it executes after a join point regardless of join point exit whether
normally or exceptional return.
o Around Advice: It executes before and after a join point.
Pointcut
It is an expression language of AOP that matches join points.
Introduction
It means introduction of additional method and fields for a type. It allows you to introduce new
interface to any advised object.
Target Object
It is the object i.e. being advised by one or more aspects. It is also known as proxied object in
spring because Spring AOP is implemented using runtime proxies.
Aspect
It is a class that contains advices, joinpoints etc.
Interceptor
It is an aspect that contains only one advice.
AOP Proxy
It is used to implement aspect contracts, created by AOP framework. It will be a JDK dynamic
proxy or CGLIB proxy in spring framework.
Weaving
It is the process of linking aspect with other application types or objects to create an advised
object. Weaving can be done at compile time, load time or runtime. Spring AOP performs
weaving at runtime.
AOP Implementations
AOP implementations are provided by:
1. AspectJ
2. Spring AOP
3. JBoss AOP
a. Before: Runs before the advised method is invoked. It is denoted by @Before annotation.
b. After: Runs after the advised method completes regardless of the outcome, whether
successful or not. It is denoted by @After annotation.
c. AfterReturning: Runs after the advised method successfully completes ie without any
runtime exceptions. It is denoted by @AfterReturning annotation.
d. Around: This is the strongest advice among all the advice since it wraps around and runs
before and after the advised method. This type of advice is used where we need frequent
access to a method or database like- caching. It is denoted by @Around annotation.
e. AfterThrowing: Runs after the advised method throws a Runtime Exception. It is denoted
by @AfterThrowing annotation.
Bean Scopes
Bean Scopes refers to the lifecycle of Bean that means when the object of Bean will be
instantiated, how long does that object live, and how many objects will be created for that bean
throughout. Basically, it controls the instance creation of the bean and it is managed by the
spring container.
Bean Scopes in Spring
The spring framework provides five scopes for a bean. We can use three of them only in the
context of web-aware Spring ApplicationContext and the rest of the two is available for
both IoC container and Spring-MVC container. The following are the different scopes
provided for a bean:
1. Singleton: Only one instance will be created for a single bean definition per Spring IoC
container and the same object will be shared for each request made for that bean.
2. Prototype: A new instance will be created for a single bean definition every time a request
is made for that bean.
3. Request: A new instance will be created for a single bean definition every time an HTTP
request is made for that bean. But Only valid in the context of a web-aware Spring
ApplicationContext.
4. Session: Scopes a single bean definition to the lifecycle of an HTTP Session. But Only
valid in the context of a web-aware Spring ApplicationContext.
5. Global-Session: Scopes a single bean definition to the lifecycle of a global HTTP Session.
It is also only valid in the context of a web-aware Spring ApplicationContext.
Singleton Scope:
If the scope is a singleton, then only one instance of that bean will be instantiated per Spring
IoC container and the same instance will be shared for each request. That is when the scope of
a bean is declared singleton, then whenever a new request is made for that bean, spring IOC
container first checks whether an instance of that bean is already created or not. If it is already
created, then the IOC container returns the same instance otherwise it creates a new instance of
that bean only at the first request. By default, the scope of a bean is a singleton.
Step1: Lets first create a bean (i.e.), the backbone of the application in the spring
framework.
package bean;
public class HelloWorld {
public String name;
// Create a setter method to
// set the value passed by user
public void setName(String name)
{
this.name = name;
}
// Create a getter method so that the user can get the set value
public String getName()
{
return name;
}
}
Step 2: Now, we write a Spring XML configuration file “spring.xml” and configure the bean
defined above.
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd ">
<beans>
<!--configure the bean HelloWorld.java
and declare its scope-->
< bean
id = "hw"
class= "bean.HelloWorld"
scope = "singleton" / >
</beans>
Step 3: Finally, write a driver class “Client.java” to request the above bean.
package driver;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bean.HelloWorld;
// Client Class to request the above defined bean
public class Client {
public static void main(String[] args)
{
// Load the Spring XML configuration file into IoC container
ApplicationContext ap = new ClassPathXmlApplicationContext(
"resources/spring.xml");
// Get the "HelloWorld" bean object and call getName() method
HelloWorld Geeks1 = (HelloWorld)ap.getBean("hw");
// Set the name
Geeks1.setName("Geeks1");
System.out.println( "Hello object (hello1)" + " Your name is: "
+ Geeks1.getName());
// Get another "HelloWorld" bean object and call getName() method
HelloWorld Geeks2 = (HelloWorld)ap.getBean("hw");
System.out.println( "Hello object (hello2)" + " Your name is: "
+ Geeks2.getName());
// Now compare the references to see whether they are pointing to the
// same object or different object
System.out.println( "'Geeks1' and 'Geeks2'" + " are referring" + "to the same object: "
+ (Geeks1 == Geeks2));
// Print the address of both object Geeks1 and Geeks2
System.out.println( "Address of object Geeks1: " + Geeks1);
System.out.println("Address of object Geeks2: " + Geeks2);
}
}
Output:
Hello object (hello1) Your name is: Geeks1
Hello object (hello2) Your name is: Geeks1
'Geeks1' and 'Geeks2' are referring to the same object: true
Address of object Geeks1: bean.HelloWorld@627551fb
Address of object Geeks2: bean.HelloWorld@627551fb
Explanation: When we call the getName() method by using the reference of ‘Geeks1’ and
‘Geeks2’, then we are getting the same outputs. This means that both the reference is
calling the getName() method of the same object. Furthermore, when we are comparing the
reference ‘Geeks1’ and ‘Geeks2’ then output is “true” which means the same object is
shared between ‘Geeks1’ and ‘Geeks2’. So it is clear that a new instance of bean
(HelloWorld) is created when we made the request the first time and for each new request,
the same object is being shared.
Prototype Scope:
If the scope is declared prototype, then spring IOC container will create a new instance of that
bean every time a request is made for that specific bean. A request can be made to the bean
instance either programmatically using getBean() method or by XML for Dependency
Injection of secondary type. Generally, we use the prototype scope for all beans that are
stateful, while the singleton scope is used for the stateless beans.
Let’s understand this scope with an example:
Step 1: Let us first create a bean (i.e.), the backbone of the application in the spring
framework.
package bean;
public class HelloWorld {
public String name;
// Create a setter method to set the value passed by user
public void setName(String name)
{
this.name = name;
}
// Create a getter method so that the user can get the set value
public String getName()
{
return name;
}
}
Step 2: Now, we write a Spring XML configuration file “spring.xml” and configure the bean
defined above.
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd ">
< beans>
<!--configure the bean HelloWorld.java and declare its scope-->
< bean id = "hw"
class = "bean.HelloWorld"
scope = "prototype" / >
</ beans>
Step 3: Finally, write a driver class “Client.java” to request the above bean.
package driver;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bean.HelloWorld;
public class Client {
public static void main(String[] args)
{
// Load the Spring XML configuration file into IoC container
ApplicationContext ap= new ClassPathXmlApplicationContext( "resources/spring.xml");
// Get the "HelloWorld" bean object and call getName() method
HelloWorld Geeks1 = (HelloWorld)ap.getBean("hw");
// Set the name
Geeks1.setName("Geeks1");
System.out.println("Hello object (hello1)" + " Your name is: " + Geeks1.getName());
// Get another "HelloWorld" bean object and call getName() method
HelloWorld Geeks2= (HelloWorld)ap.getBean("hw");
System.out.println("Hello object (hello2)"+ "Your name is: " + Geeks2.getName());
// Now compare the references to see whether they are pointing the same object or
different object
System.out.println( "'Geeks1' and 'Geeks2'" + "are referring " + "to the same object: " +
(Geeks1 == Geeks2));
// Print the address of both object Geeks1 and Geeks2
System.out.println("Address of object Geeks1: "+ Geeks1);
System.out.println("Address of object Geeks2: "+ Geeks2);
}
}
Output:
Hello object (hello1) Your name is: Geeks1
Hello object (hello2) Your name is: null
'Geeks1' and 'Geeks2' are referring to the same object: false
Address of object Geeks1: bean.HelloWorld@47ef968d
Address of object Geeks2: bean.HelloWorld@23e028a9
Explanation: When we call getName() method by using the reference ‘Geeks1’ and
‘Geeks2’, then we get different outputs that means both the reference is calling getName()
method of a different object. Furthermore, when we are comparing the reference ‘Geeks1’
and ‘Geeks2’ then output is “false” which means both references is referring to a different
object. So it is clear that a new instance of bean (HelloWorld) is being created at each
request made for this bean.
Difference between Singleton and Prototype
Singleton Prototype
Same object is shared for each request made for For each new request a new instance is
that bean. i.e. The same object is returned each created. i.e. A new object is created each
time it is injected. time it is injected.
Singleton scope should be used for stateless While prototype scope is used for all beans
beans. that are stateful
Request, Session, Application, and WebSocket Scopes
The request, session, application, and websocket scopes are available only if you use a web-
aware Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you
use these scopes with regular Spring IoC containers, such as
the ClassPathXmlApplicationContext, an IllegalStateException that complains about an
unknown bean scope is thrown.
Initial Web Configuration
To support the scoping of beans at the request, session, application, and websocket levels (web-
scoped beans), some minor initial configuration is required before you define your beans. (This
initial setup is not required for the standard scopes: singleton and prototype.)
How you accomplish this initial setup depends on your particular Servlet environment.
If you access scoped beans within Spring Web MVC, in effect, within a request that is processed
by the Spring DispatcherServlet, no special setup is necessary. DispatcherServlet already
exposes all relevant state.
If you use a Servlet web container, with requests processed outside of
Spring’s DispatcherServlet (for example, when using JSF), you need to register
the org.springframework.web.context.request.RequestContextListener ServletRequestListener.
This can be done programmatically by using the WebApplicationInitializer interface.
Alternatively, add the following declaration to your web application’s web.xml file:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
Copied!
Alternatively, if there are issues with your listener setup, consider using
Spring’s RequestContextFilter. The filter mapping depends on the surrounding web application
configuration, so you have to change it as appropriate. The following listing shows the filter part
of a web application:
<web-app>
...
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-
class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
Copied!
DispatcherServlet, RequestContextListener, and RequestContextFilter all do exactly the same
thing, namely bind the HTTP request object to the Thread that is servicing that request. This
makes beans that are request- and session-scoped available further down the call chain.
Request scope
Consider the following XML configuration for a bean definition:
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
Copied!
The Spring container creates a new instance of the LoginAction bean by using
the loginAction bean definition for each and every HTTP request. That is, the loginAction bean
is scoped at the HTTP request level. You can change the internal state of the instance that is
created as much as you want, because other instances created from the same loginAction bean
definition do not see these changes in state. They are particular to an individual request. When
the request completes processing, the bean that is scoped to the request is discarded.
When using annotation-driven components or Java configuration,
the @RequestScope annotation can be used to assign a component to the request scope.
Session Scope
Consider the following XML configuration for a bean definition:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
Copied!
The Spring container creates a new instance of the UserPreferences bean by using
the userPreferences bean definition for the lifetime of a single HTTP Session. In other words,
the userPreferences bean is effectively scoped at the HTTP Session level. As with request-scoped
beans, you can change the internal state of the instance that is created as much as you want,
knowing that other HTTP Session instances that are also using instances created from the
same userPreferences bean definition do not see these changes in state, because they are
particular to an individual HTTP Session. When the HTTP Session is eventually discarded, the
bean that is scoped to that particular HTTP Session is also discarded.
Application Scope
Consider the following XML configuration for a bean definition:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
Copied!
The Spring container creates a new instance of the AppPreferences bean by using
the appPreferences bean definition once for the entire web application. That is,
the appPreferences bean is scoped at the ServletContext level and stored as a
regular ServletContext attribute. This is somewhat similar to a Spring singleton bean but differs
in two important ways: It is a singleton per ServletContext, not per
Spring ApplicationContext (for which there may be several in any given web application), and it
is actually exposed and therefore visible as a ServletContext attribute.
WebSocket Scope
Each WebSocket session has a map of attributes. The map is attached as a header to inbound
client messages and may be accessed from a controller method, as the following example shows:
@Controller
public class MyController {
@MessageMapping("/action")
public void handle(SimpMessageHeaderAccessor headerAccessor) {
Map<String, Object> attrs = headerAccessor.getSessionAttributes();
// ...
}
}
ed!
You can declare a Spring-managed bean in the websocket scope. You can inject WebSocket-
scoped beans into controllers and any channel interceptors registered on
the clientInboundChannel. Those are typically singletons and live longer than any individual
WebSocket session.
Autowiring in Spring
Autowiring feature of spring framework enables you to inject the object dependency implicitly.
It internally uses setter or constructor injection.
Autowiring can't be used to inject primitive and string values. It works with reference only.
Advantage of Autowiring
It requires the less code because we don't need to write the code to inject the dependency
explicitly.
Disadvantage of Autowiring
No control of programmer.
It can't be used for primitive and string values.
Autowiring Modes
There are many autowiring modes:
No Mode Description
.
2) byName The byName mode injects the object dependency according to name of the bean.
In such case, property name and bean name must be same. It internally calls
setter method.
3) byType The byType mode injects the object dependency according to type. So property
name and bean name can be different. It internally calls setter method.
4) constructor The constructor mode injects the dependency by calling the constructor of the
class. It calls the constructor having large number of parameters.
4) no autowiring mode
In case of no autowiring mode, spring container doesn't inject the dependency by autowiring.
1. <bean id="b" class="org.sssit.B"></bean>
2. <bean id="a" class="org.sssit.A" autowire="no"></bean>
Spring Framework Annotations
Spring framework is one of the most popular Java EE frameworks. It is an open-source
lightweight framework that allows Java EE 7 developers to build simple, reliable, and scalable
enterprise applications. This framework mainly focuses on providing various ways to help you
manage your business objects. Now talking about Spring Annotation, Spring Annotations are a
form of metadata that provides data about a program. Annotations are used to provide
supplemental information about a program. It does not have a direct effect on the operation of
the code they annotate. It does not change the action of the compiled program. So in this
article, we are going to discuss what are the main types of annotation that are available in the
spring framework with some examples.
Types of Spring Framework Annotations
Basically, there are 6 types of annotation available in the whole spring framework.
1. Spring Core Annotations
2. Spring Web Annotations
3. Spring Boot Annotations
4. Spring Scheduling Annotations
5. Spring Data Annotations
6. Spring Bean Annotations
Type 1: Spring Core Annotations
Spring annotations present in
the org.springframework.beans.factory.annotation and org.springframework.context.annotat
ion packages are commonly known as Spring Core annotations. We can divide them into two
categories:
DI-Related Annotations
o @Autowired
o @Qualifier
o @Primary
o @Bean
o @Lazy
o @Required
o @Value
o @Scope
o @Lookup, etc.
Context Configuration Annotations
o @Profile
o @Import
o @ImportResource
o @PropertySource, etc.
A DI (Dependency Injection) Related Annotations
1.1: @Autowired
@Autowired annotation is applied to the fields, setter methods, and constructors. It injects
object dependency implicitly. We use @Autowired to mark the dependency that will be
injected by the Spring container.
1.2: Field injection
class Student {
@Autowired
Address address;
}
1.3: Constructor injection
class Student {
Address address;
@Autowired
Student(Address address) {
this.address = address;
}
}
1.4: Setter injection
class Student {
Address address;
@Autowired
void setaddress(Address address) {
this.address = address;
}
}
B Context Configuration Annotations
@Profile: If you want Spring to use a @Component class or a @Bean method only when a
specific profile is active then you can mark it with @Profile.
@Component
@Profile("developer")
public class Employee {}
Type 2: Spring Web Annotations
Spring annotations present in the org.springframework.web.bind.annotation packages are
commonly known as Spring Web annotations. Some of the annotations that are available in this
category are:
@RequestMapping
@RequestBody
@PathVariable
@RequestParam
Response Handling Annotations
o @ResponseBody
o @ExceptionHandler
o @ResponseStatus
@Controller
@RestController
@ModelAttribute
@CrossOrigin
Example: @Controller
Spring @Controller annotation is also a specialization of @Component annotation. The
@Controller annotation indicates that a particular class serves the role of a controller. Spring
Controller annotation is typically used in combination with annotated handler methods based
on the @RequestMapping annotation. It can be applied to classes only. It’s used to mark a
class as a web request handler. It’s mostly used with Spring MVC applications. This annotation
acts as a stereotype for the annotated class, indicating its role. The dispatcher scans such
annotated classes for mapped methods and detects @RequestMapping annotations.
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class DemoController {
@RequestMapping("/hello")
@ResponseBody
public String helloGFG()
{
return "Hello GeeksForGeeks";
}
}
Type 3: Spring Boot Annotations
Spring annotations present in
the org.springframework.boot.autoconfigure and org.springframework.boot.autoconfigure.c
ondition packages are commonly known as Spring Boot annotations. Some of the annotations
that are available in this category are:
@SpringBootApplication
@EnableAutoConfiguration
Auto-Configuration Conditions
o @ConditionalOnClass, and @ConditionalOnMissingClass
o @ConditionalOnBean, and @ConditionalOnMissingBean
o @ConditionalOnProperty
o @ConditionalOnResource
o @ConditionalOnWebApplication and @ConditionalOnNotWebApplication
o @ConditionalExpression
o @Conditional
Example: @SpringBootApplication
This annotation is used to mark the main class of a Spring Boot application. It encapsulates
@Configuration, @EnableAutoConfiguration, and @ComponentScan annotations with their
default attributes.
public class DemoApplication {
// Main driver method
public static void main(String[] args)
{
SpringApplication.run(DemoApplication.class, args);
}
}
Type 4: Spring Scheduling Annotations
Spring annotations present in the org.springframework.scheduling.annotation packages are
commonly known as Spring Scheduling annotations. Some of the annotations that are available
in this category are:
@EnableAsync
@EnableScheduling
@Async
@Scheduled
@Schedules
Example: @EnableAsync
This annotation is used to enable asynchronous functionality in Spring.
@Configuration
@EnableAsync
class Config {}
Type 5: Spring Data Annotations
Spring Data provides an abstraction over data storage technologies. Hence the business logic
code can be much more independent of the underlying persistence implementation. Some of
the annotations that are available in this category are:
Common Spring Data Annotations
o @Transactional
o @NoRepositoryBean
o @Param
o @Id
o @Transient
o @CreatedBy, @LastModifiedBy, @CreatedDate, @LastModifiedDate
Spring Data JPA Annotations
o @Query
o @Procedure
o @Lock
o @Modifying
o @EnableJpaRepositories
Spring Data Mongo Annotations
o @Document
o @Field
o @Query
o @EnableMongoRepositories
Example:
A @Transactional
When there is a need to configure the transactional behavior of a method, we can do it with
@Transactional annotation.
@Transactional
void payment() {}
B @Id: @Id marks a field in a model class as the primary key. Since it’s implementation-
independent, it makes a model class easy to use with multiple data store engines.
class Student {
@Id
Long id;
// other fields
// ...........
}
Type 6: Spring Bean Annotations
There’re several ways to configure beans in a Spring container. You can declare them using
XML configuration or you can declare beans using the @Bean annotation in a configuration
class or you can mark the class with one of the annotations from
the org.springframework.stereotype package and leave the rest to component scanning. Some
of the annotations that are available in this category are:
@ComponentScan
@Configuration
Stereotype Annotations
o @Component
o @Service
o @Repository
o @Controller
Example: Stereotype Annotations
Spring Framework provides us with some special annotations. These annotations are used to
create Spring beans automatically in the application context. @Component annotation is the
main Stereotype Annotation. There are some Stereotype meta-annotations which is derived
from @Component those are
1. @Service
2. @Repository
3. @Controller
1: @Service: We specify a class with @Service to indicate that they’re holding the business
logic. Besides being used in the service layer, there isn’t any other special use for this
annotation. The utility classes can be marked as Service classes.
2: @Repository: We specify a class with @Repository to indicate that they’re dealing
with CRUD operations, usually, it’s used with DAO (Data Access Object) or Repository
implementations that deal with database tables.
3: @Controller: We specify a class with @Controller to indicate that they’re front controllers
and responsible to handle user requests and return the appropriate response. It is mostly used
with REST Web Services.
Life Cycle Call backs
The Spring bean life cycle is easy to understand. When a bean is instantiated, it may be required
to perform some initialization to get it into a usable state. Similarly, when the bean is no longer
required and is removed from the container, some cleanup may be required.
Though, there is lists of the activities that take place behind the scenes between the time of bean
Instantiation and its destruction, but this chapter will discuss only two important bean life cycle
callback methods which are required at the time of bean initialization and its destruction.
Beans can be notified after creation and all properties are set, and before they are destroyed and
removed from the bean container. This involves specifying the callback method to be invoked by
the container. This is done in XML by specifying attributes init-method=”myinit”, for the
initialization callback, and destroy-method=”mydestroy”, for the destroy callback. “myinit” and
“cleanUp” are names of instance methods in the bean class.
Initialization callbacks
Implementing the org.springframework.beans.factory.InitializingBean interface allows a bean to
perform initialization work after all necessary properties on the bean are set by the container. The
InitializingBean interface specifies exactly one method:
org.springframework.beans.factory.InitializingBean interface provide Initialization callbacks
method as given below..
Now we can implements above interface and do some initialization functionality with in this
method.
// Method
public void displayInfo()
{
// Print statement
System.out.println("Student Name is " + studentName
+ " and Roll Number is " + id);
}
}
Now let’s create an XML file named beans.xml file in the project classpath. And inside this
beans.xml file, we have to define our Student bean something like this. And that’s it. In this
way, you can create beans in spring.
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
</bean>
</beans>
Method 2: Using @Component Annotation
Spring Annotations are a form of metadata that provides data about a program. Annotations are
used to provide supplemental information about a program. It does not have a direct effect on
the operation of the code they annotate. It does not change the action of the compiled
program. @Component is an annotation that allows Spring to automatically detect the custom
beans.
Example: Suppose we have already a Java project and all the Spring JAR files are imported
into that project. Now let’s create a simple class named College and inside the class, we have a
simple method. Below is the code for the College.java file.
A. File: College.java
public class College {
// Method
public void test()
{
// Print statement
// whenever this method is called
System.out.println("Test College Method");
}
}
Now let’s create a Bean for this class. So we can use @Component annotation for doing the
same task. So we can modify our College.java file something like this. And that’s it.
B. College.java
package ComponentAnnotation;
@Component("collegeBean")
// Class
public class College {
// Method
public void test()
{
// Print statement
System.out.println("Test College Method");
}
}
Method 3: Using @Bean Annotation
One of the most important annotations in spring is the @Bean annotation which is applied on
a method to specify that it returns a bean to be managed by Spring context. Spring Bean
annotation is usually declared in Configuration classes methods.
Suppose we have already a Java project and all the Spring JAR files are imported into that
project. Now let’s create a simple class named College and inside the class, we have a simple
method. Below is the code for the College.java file.
A. College.java
package BeanAnnotation;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CollegeConfig {
}
Here, we are going to create the spring beans using the @Bean annotation. To create the
College class bean using the @Bean annotation inside the configuration class we can write
something like this inside our CollegeConfig.java file.
Spring Boot
Spring Boot is a Java framework that makes it easier to create and run Java applications. It
simplifies the configuration and setup process, allowing developers to focus more on writing
code for their applications.
This Spring Boot Tutorial is a comprehensive guide that covers both basic and advanced
concepts of the Spring Framework. It is designed for beginners as well as professionals.
Spring Boot, a module of the Spring framework, facilitates Rapid Application
Development (RAD) capabilities.
This Spring tutorial includes basic to advanced topics of Spring Boot, like Basics of Spring
Boot, Spring Boot core, Spring Boot REST API, Spring Boot with Microservices, Spring Boot
with Kafka, Spring Boot with Database and Data JPA, etc.
What is Spring Boot?
Spring Boot is an open-source Java framework used to create a Micro Service. Spring boot is
developed by Pivotal Team, and it provides a faster way to set up and an easier, configure, and
run both simple and web-based applications. It is a combination of Spring Framework and
Embedded Servers. The main goal of Spring Boot is to reduce development, unit test, and
integration test time and in Spring Boot, there is no requirement for XML configuration.
Advantages of Spring Boot
o It creates stand-alone Spring applications that can be started using Java -jar.
o It tests web applications easily with the help of different Embedded HTTP servers such
as Tomcat, Jetty, etc. We don't need to deploy WAR files.
o It provides opinionated 'starter' POMs to simplify our Maven configuration.
o It provides production-ready features such as metrics, health checks, and externalized
configuration.
o There is no requirement for XML configuration.
o It offers a CLI tool for developing and testing the Spring Boot application.
o It offers the number of plug-ins.
o It also minimizes writing multiple boilerplate codes (the code that has to be included in
many places with little or no alteration), XML configuration, and annotations.
o It increases productivity and reduces development time.
Limitations of Spring Boot
Spring Boot can use dependencies that are not going to be used in the application. These
dependencies increase the size of the application.
Spring Boot Build Systems
Any software system needs a build system to generate a deployable artefact. For example, the
artefact for java based applications can be JAR, WAR, or EAR. The build tool helps in building
the application and creating the artefact. Though many build tools exist in the
market, maven and Gradle are popular.
Introduction to Build Systems in SpringBoot
Maven and Gradle are the two most popular build tools to build java based applications. Both
support dependency management and consume artifactory from maven central.
Maven
This section will cover all dependencies and plugins required to build the spring
boot application.
Inheriting the starter Parent
Every spring boot application must inherit the starter-parent dependency to use spring boot
defaults.
The starter parent inherits from spring-boot-dependencies, which contains all dependency
versions for all the framework that works with spring boot and are compatible with each other.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Starter parent provides:
Provide the default compiler level as Java 1.8.
Provides a default configuration for maven-surefire-plugin, maven-jar-plugin,
and maven-failsafe-plugin.
Using Spring Boot without the Parent POM
There can be a situation in that you can not inherit from starter-parent dependency because your
corporate has its parent pom, which must be inherited. In such cases, spring boot provides an
alternate way to take advantage of dependency management.
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Changing the Java Version
Spring boot by default assumes the application is using java 8, but it can be overridden using the
maven property java.version
<properties>
<java.version>17</java.version>
</properties>
Using the Spring Boot Maven plugin
Spring Boot includes a Maven plugin that can package the project as an executable jar. Add the
plugin to your <plugins> section.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
The final pom will look like the below:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(ApplicationArguments arg0) throws Exception {
System.out.println("Hello World from Application Runner");
}
}
Command Line Runner
Command Line Runner is an interface. It is used to execute the code after the Spring Boot
application started. The example given below shows how to implement the Command Line
Runner interface on the main class file.
package com.tutorialspoint.demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... arg0) throws Exception {
System.out.println("Hello world from Command Line Runner");
}
}
Logger
Logging in Spring Boot plays a vital role in Spring Boot applications for recording
information, actions, and events within the app. It is also used for monitoring the performance
of an application, understanding the behavior of the application, and recognizing the issues
within the application. Spring Boot offers flexible logging capabilities by providing various
logging frameworks and also provides ways to manage and configure the logs.
Why to use Spring Boot – Logging?
A good logging infrastructure is necessary for any software project as it not only helps in
understanding what’s going on with the application but also to trace any unusual incident or
error present in the project. This article covers several ways in which logging can be enabled in
a spring boot project through easy and simple configurations. Let’s first do the initial setup to
explore each option in more depth.
Elements of Logging Framework
Logger: It captures the messages.
Formatter: It formats the messages which are captured by loggers.
Handler: It prints messages on the console, stores them in a file or sends an email, etc.
// Rest Controller to print various log level messages
package com.log.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogController {
// creating a logger
Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/log") public String log()
{
// Logging various log level messages
logger.trace("Log level: TRACE");
logger.info("Log level: INFO");
logger.debug("Log level: DEBUG");
logger.error("Log level: ERROR");
logger.warn("Log level: WARN");
return "Hey! You can check the output in the logs";
}
}
RestController: RestController is used for making restful web services with the help of the
@RestController annotation. This annotation is used at the class level and allows the class to
handle the requests made by the client. Let’s understand @RestController annotation using an
example. The RestController allows to handle all REST APIs such
as GET, POST, Delete, PUT requests.
Spring Initializr is a web-based tool using which we can easily generate the structure of the
Spring Boot project. It also provides various different features for the projects expressed in a
metadata model. This model allows us to configure the list of dependencies that are supported
by JVM. Here, we will create the structure of an application using a spring initializer and then
use an IDE to create a sample GET route. Therefore, to do this, the following steps are
followed sequentially as follows.
Step by Step Implementation
Step 1: Go to Spring Initializr
Fill in the details as per the requirements. For this application:
Project: Maven
Language: Java
Spring Boot: 2.2.8
Packaging: JAR
Java: 8
Dependencies: Spring Web
Step 2: Click on Generate which will download the starter project
Step 3: Extract the zip file. Now open a suitable IDE and then go to File > New > Project from
existing sources > Spring-boot-app and select pom.xml. Click on import changes on prompt
and wait for the project to sync as pictorially depicted below as follows:
Note: In the Import Project for Maven window, make sure you choose the same version of JDK
which you selected while creating the project.
Step 4: Go to src > main > java > com.gfg.Spring.boot.app, create a java class with the name
Controller and add the annotation @RestController and other class named as Details.
@RequestMapping
This annotation is a versatile and flexible annotation that can be used with a controller (class)
as well as the methods to map specific web requests with the handler methods and controllers.
This annotation is part of a larger set of annotations provided by Spring Framework to define
URL endpoints and simplify the development of Spring Boot applications.
It has the following features:
Define several different endpoints to access a specific resource.
Build REST APIs to serve web requests.
Simplify the web development process by simply defining an annotation that offers a set of
functionalities for handling requests.
Define multiple endpoints in a single @RequestMapping annotation.
Step-By-Step Implementation of @RequestMapping annotation
For this article, we’ll be using the following tools:
Java 8 or higher
Java IDE like Eclipse, IntelliJ, and VS code (We’ll be using IntelliJ)
POSTMAN for testing Request Mappings
Dependency: Spring Web Starter
Step-1: Create a starter file and extract it
Go to Spring Initializr and create a starter file having a single dependency – Spring Web.
A request body is data sent by the client to your API. A response body is the data your API
sends to the client.
Your API almost always has to send a response body. But clients don't necessarily need to
send request bodies all the time.
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
When building RESTful APIs with Spring Boot, it’s crucial to extract data from incoming
HTTP requests to process and respond accordingly. The Spring framework provides two main
annotations for this purpose: @PathVariable and @RequestParam.
The @PathVariable annotation is used to retrieve data from the URL path. By defining
placeholders in the request mapping URL, you can bind those placeholders to method
parameters annotated with @PathVariable. This allows you to access dynamic values from
the URL and use them in your code. For example, you can extract a user ID from a URL
like /users/123 and pass it to a method that retrieves the corresponding user’s details.
On the other hand, the @RequestParam annotation enables you to extract data from the
query parameters in the request URL. Query parameters are key-value pairs appended to the
URL after a question mark (?). With @RequestParam, you can specify the name of the
parameter to retrieve and bind it to a method parameter. This is useful when you need to
pass additional information or filters to your API endpoints. For instance, you can extract
the value of a name parameter from a URL like /users/search?name=John and use it to
search for users with the given name.
Both @PathVariable and @RequestParam annotations simplify the process of extracting
data from incoming requests in Spring Boot. They provide a clean and declarative way to
access dynamic values from URLs and query parameters, making it easier to handle and
process request data in your REST API endpoints.
By leveraging these annotations effectively, you can enhance the functionality of your Spring
Boot applications, create more flexible APIs, and provide better user experiences by allowing
clients to pass relevant data in their requests. Here’s a detailed explanation of the
@PathVariable and @RequestParam annotations in Spring Boot, along with full source code
examples:
Using @PathVariable
The @PathVariable annotation is used to extract data from the URL path. It allows you to
define placeholders in your request mapping URL and bind those placeholders to method
parameters. Let’s consider an example where you have a REST API endpoint for retrieving a
user’s details by their ID:
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{userId}")
public ResponseEntity<User> getUserDetails(@PathVariable Long userId) {
// Implementation to fetch user details based on the provided userId
// ...
return ResponseEntity.ok(user);
}
}
Using @RequestParam
The @RequestParam annotation is used to extract data from the query parameters in the
request URL. Query parameters are the key-value pairs that appear after the ? in a URL. Let’s
consider an example where you have a REST API endpoint for searching users based on a
query parameter:
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(@RequestParam("name") String name) {
// Implementation to search users based on the provided name
// ...
return ResponseEntity.ok(users);
}
}
Build Web Applications