Unit 5 Spring Framework
Unit 5 Spring Framework
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.
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.
Fast Development
The Dependency Injection feature of Spring Framework and it support to various frameworks
makes the easy development of JavaEE application.
Powerful abstraction
It provides powerful abstraction to JavaEE specifications such as JMS, JDBC,JPA and JTA.
Declarative support
It provides declarative support for caching, validation, transactions and formatting.
Spring Core Concepts - DI, IoC, AOP
Dependency Injection
Inversion of Control.
DI-Dependency Injection
Dependency Injection (DI) is a design pattern that removes the dependency from the
programming code so that it can be easy to manage and test the application.
Dependency Injection makes our programming code loosely coupled.
public class
Employee{Address address;
Employee(Address address)
{this.address=address; //not creating instance }}
IoC Container
The IoC container is responsible to instantiate, configure and assemble the objects.
The IoC container gets information’s from the XML file and works accordingly. The
main tasks performed by IoC container are:
1. BeanFactory
2. ApplicationContext
interfaces acts as the IoC container. The ApplicationContext interface is built on top of
the BeanFactory interface. It adds some extra functionality than BeanFactory such as
simple integration with Spring's AOP, message resource handling (for I18N), event
propagation, application layer specific context (e.g. WebApplicationContext) for web
application. So it is better to use ApplicationContext than BeanFactory.
Using BeanFactory
The XmlBeanFactory is the implementation class for the BeanFactory interface. To use
the BeanFactory, we need to create the instance of XmlBeanFactory class as given
below:
Using ApplicationContext
The ClassPathXmlApplicationContext class is the implementation class of
ApplicationContext interface. We need to instantiate the
ClassPathXmlApplicationContext class to use the ApplicationContext as given below:
1. ApplicationContext context =
2. new ClassPathXmlApplicationContext("applicationContext.xml");
o By Constructor
o By Setter method
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.
3. public class Employee {
4. private int id;
5. private String name;
6.
7. public Employee() {System.out.println("def cons");}
8.
9. public Employee(int id) {this.id = id;}
10.
11.public Employee(String name) { this.name = name;}
12.
13.public Employee(int id, String name) {
14. this.id = id;
15. this.name = name;
16.}
17.
18.void show(){
19. System.out.println(id+" "+name);
20.}
21.
applicationContext.xml
We are providing the information into the bean by this file. The constructor-arg
element invokes the constructor. In such case, parameterized constructor of int type
will be invoked. The value attribute of constructor-arg element will assign the
specified value. The type attribute specifies that int parameter constructor will be
invoked.
Test.java
This class gets the bean from the applicationContext.xml file and calls the show
method.
1. package com.javatpoint;
2.
3. import org.springframework.beans.factory.BeanFactory;
4. import org.springframework.beans.factory.xml.XmlBeanFactory;
5. import org.springframework.core.io.*;
6.
7. public class Test {
8. public static void main(String[] args) {
9.
10. Resource r=new ClassPathResource("applicationContext.xml");
11. BeanFactory factory=new XmlBeanFactory(r);
12.
13. Employee s=(Employee)factory.getBean("e");
14. s.show();
15.
16. }
17.}
Output:10 null
We can inject the dependency by setter method also. The <property> subelement
of <bean> is used for setter injection. Here we are going to inject
o Employee.java
o applicationContext.xml
o Test.java
Employee.java
It is a simple class containing three fields id, name and city with its setters and getters
and a method to display these informations.
1. package com.javatpoint;
2.
3. public class Employee {
4. private int id;
5. private String name;
6. private String city;
7.
8. public int getId() {
9. return id;
10.}
11.public void setId(int id) {
12. this.id = id;
13.}
14.public String getName() {
15. return name;
16.}
17.public void setName(String name) {
18. this.name = name;
19.}
20.
21.public String getCity() {
22. return city;
23.}
24.public void setCity(String city) {
25. this.city = city;
26.}
27.void display(){
28. System.out.println(id+" "+name+" "+city);
29.}
30.
31.}
applicationContext.xml
We are providing the information into the bean by this file. The property element
invokes the setter method. The value subelement of property will assign the specified
value.
Test.java
This class gets the bean from the applicationContext.xml file and calls the display
method.
1. package com.javatpoint;
2.
3. import org.springframework.beans.factory.BeanFactory;
4. import org.springframework.beans.factory.xml.XmlBeanFactory;
5. import org.springframework.core.io.*;
6.
7. public class Test {
8. public static void main(String[] args) {
9.
10. Resource r=new ClassPathResource("applicationContext.xml");
11. BeanFactory factory=new XmlBeanFactory(r);
12.
13. Employee e=(Employee)factory.getBean("obj");
14. s.display();
15.
16. }
17.}
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.
It provides the pluggable way to dynamically add the additional concern before, after
or around the actual logic. Suppose there are 10 methods in a class as given below:
1. class A{
2. public void m1(){...}
3. public void m2(){...}
4. public void m3(){...}
5. public void m4(){...}
6. public void m5(){...}
7. public void n1(){...}
8. public void n2(){...}
9. public void p1(){...}
10.public void p2(){...}
11.public void p3(){...}
12.}
There are 5 methods that starts from m, 2 methods that starts from n and 3 methods
that starts from p.
Understanding Scenario I have to maintain log and send notification after calling
methods that starts from m.
Problem without AOP We can call methods (that maintains log and sends
notification) from the methods starting with m. In such scenario, we need to write the
code in all the 5 methods.
But, if client says in future, I don't have to send notification, you need to change all
the methods. It leads to the maintenance problem.
Solution with AOP We don't have to call methods from the method. Now we can
define the additional concern like maintaining log, sending notification etc. in the
method of a class. Its entry is given in the xml file.
In future, if client says to remove the notifier functionality, we need to change only in
the xml file. So, maintenance is easy in AOP.
o Join point
o Advice
o Pointcut
o Introduction
o Target Object
o Aspect
o Interceptor
o AOP Proxy
o Weaving
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:
Pointcut
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
AOP Proxy
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.
The Spring Beans are Java Objects that form the backbone of a Spring application.
They are instantiated, assembled, and managed by the Spring IoC container.
These beans are created with the configuration metadata that is supplied to the
container, for example, in the form of XML <bean/> definitions. Beans defined in
spring framework are singleton beans. There is an attribute in bean tag named
"singleton" if specified true then bean becomes singleton and if set to false then
the bean becomes a prototype bean. By default it is set to true. So, all the beans in
spring framework are by default singleton beans.
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.
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.
Let’s us see some of them in detail:
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.
Let’s understand this scope with an example.
Step1: Lets first create a bean (i.e.), the backbone of the application in the spring
framework.
Java
package bean;
this.name = name;
return name;
Step 2: Now, we write a Spring XML configuration file “spring.xml” and configure
the bean defined above.
XML
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
< bean
id = "hw"
class= "bean.HelloWorld"
</beans>
Step 3: Finally, write a driver class “Client.java” to request the above bean.
Java
package driver;
import org.springframework
.context.ApplicationContext;
import org.springframework
.context.support
.ClassPathXmlApplicationContext;
import bean.HelloWorld;
// Client Class to request the
ApplicationContext
ap
= new ClassPathXmlApplicationContext(
"resources/spring.xml");
HelloWorld Geeks1
= (HelloWorld)ap.getBean("hw");
Geeks1.setName("Geeks1");
System.out.println(
"Hello object (hello1)"
+ Geeks1.getName());
HelloWorld Geeks2
= (HelloWorld)ap.getBean("hw");
System.out.println(
+ Geeks2.getName());
System.out.println(
+ (Geeks1 == Geeks2));
// Print the address of both
System.out.println(
+ Geeks1);
System.out.println(
+ 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.
Java
package bean;
this.name = name;
return name;
Step 2: Now, we write a Spring XML configuration file “spring.xml” and configure
the bean defined above.
XML
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
< beans>
< bean
id = "hw"
class = "bean.HelloWorld"
</ beans>
Step 3: Finally, write a driver class “Client.java” to request the above bean.
Java
package driver;
import org.springframework
.context.ApplicationContext;
import org.springframework.context.support
.ClassPathXmlApplicationContext;
import bean.HelloWorld;
ApplicationContext ap
= new ClassPathXmlApplicationContext(
"resources/spring.xml");
// Get the "HelloWorld" bean object
HelloWorld Geeks1
= (HelloWorld)ap.getBean("hw");
Geeks1.setName("Geeks1");
System.out.println(
+ Geeks1.getName());
HelloWorld Geeks2
= (HelloWorld)ap.getBean("hw");
System.out.println(
System.out.println(
+ (Geeks1 == Geeks2));
System.out.println(
+ Geeks1);
System.out.println(
+ 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
time it is injected. it is injected.
Though, there are lists of the activities that take place behind the scene
between the time of bean Instantiation and its destruction, this chapter will
discuss only two important bean life cycle callback methods, which are
required at the time of bean initialization and its destruction.
To define setup and teardown for a bean, we simply declare the <bean>
with initmethod and/or destroy-method parameters. The init-method
attribute specifies a method that is to be called on the bean immediately
upon instantiation. Similarly, destroymethod specifies a method that is
called just before a bean is removed from the container.
Initialization callbacks
The org.springframework.beans.factory.InitializingBean interface specifies a
single method −
Thus, you can simply implement the above interface and initialization work
can be done inside afterPropertiesSet() method as follows −
Destruction callbacks
The org.springframework.beans.factory.DisposableBean interface specifies a
single method −
void destroy() throws Exception;
Thus, you can simply implement the above interface and finalization work
can be done inside destroy() method as follows −
Example
Let us have a working Eclipse IDE in place and take the following steps to
create a Spring application −
Ste
Description
ps
Add required Spring libraries using Add External JARs option as explained in
2
the Spring Hello World Example chapter.
The final step is to create the content of all the Java files and Bean Configuration
5
file and run the application as explained below.
import
org.springframework.context.support.AbstractApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationConte
xt;
</beans>
Once you are done creating the source and bean configuration files, let us
run the application. If everything is fine with your application, it will print the
following message −
class Student {
@Autowired
Address address;
class Student {
Address address;
@Autowired
Student(Address address) {
this.address = address;
class Student {
Address address;
@Autowired
this.address = address;
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
@RequestMapping("/hello")
@ResponseBody
Java
@SpringBootApplication
// Class
SpringApplication.run(DemoApplication.class, args);
@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.
So the stereotype annotations in spring are @Component, @Service, @Repository,
and @Controller.
Here we are going to discuss how to create a Spring Bean in 3 different ways
as follows:
1. Creating Bean Inside an XML Configuration File (beans.xml)
2. Using @Component Annotation
3. Using @Bean Annotation
One of the most popular ways to create a spring bean is to define a bean in
an XML configuration file something like this.
<bean id="AnyUniqueId" class="YourClassName">
</bean>
Let us create a simple class Student having two attributes id and
studentName and later creating a simple method to print the details of the
student.
Example
Java
// Class
// Method
// Print statement
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.
Example
XML
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="studentAmiya" class="Student">
</bean>
</beans>
package ComponentAnnotation;
// Class
// Print statement
package ComponentAnnotation;
import org.springframework.stereotype.Component;
@Component("collegeBean")
// Class
// Method
// Print statement
package BeanAnnotation;
import org.springframework.stereotype.Component;
public class College {
package ComponentAnnotation;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
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. Please refer to the comments for a better
understanding.
@Bean
// Here the method name is the
// bean id/bean name
public College collegeBean(){
// Return the College object
return new College();
}
Implementation: Below is the complete code for
the CollegeConfig.java file that is below as follows:
Java
package BeanAnnotation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Bean
@Configuration
@ComponentScan(basePackages = "com.howtodoinjava.spring")
When component scanning is enabled, we can define the beans using one of
the following annotations as appropriate.
@Component
@Repository
@Service
@Controller
@RestController
package com.howtodoinjava.spring.service;
@Service
//...
}
Now we can load the beans in context
using AnnotationConfigApplicationContext as follows:
//Method 1
//Method 2
ctx.register(AppConfig.class);
ctx.refresh();
@Configuration
@Bean
}
}
Now we can load this bean into the application context as follows:
//Method 1
//Method 2
ctx.register(AppConfig.class);
ctx.refresh();
4. XML Configuration
XML configuration involves defining beans in XML files using
the <bean> element. While less common than annotation-based and Java
configuration, XML configuration is still supported in Spring.
<beans>
</beans>
If we have created multiple bean definition files, we can import the files in
the current file as follows:
<beans>
<import resource="employee.xml"/>
<import resource="department.xml"/>
</beans>
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
XmlWebApplicationContext
Following is an example of loading the beans.xml file
into ClassPathXmlApplicationContext. Note that the bean definition file is
located at '/src/main/resources/beans.xml'.
Program output:
Jan 02, 2018 3:10:27 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
INFO: Loading XML bean definitions from class path resource [employee.xml]
INFO: Loading XML bean definitions from class path resource [department.xml]
6. Conclusion
Configuring beans in Spring and Spring Boot is a fundamental aspect of
application development. Understanding the different ways to configure
beans and when to use each method is essential for building maintainable
and scalable applications.