Life
Cycle Management of a Spring Bean
SHARE
& COMMENT :
1)
Introduction
This
article would brief about how a Spring
Bean is
managed in IOC
(Inversion of Control) Container.
Spring Beans exist within the Container as long as they are needed by
the Application. There are various life-cycle
interfaces and
methods that will be called by the IOC
Container.
The pre-requisite for this article is some basic knowledge in Spring
which can be got by reading the article in Javabeat Introduction
to Spring Web Framework.
also
read:
2)
Bean Life Cycle
A Spring
Bean represents
a POJO
component performing
some useful operation. All Spring
Beans reside
within a Spring
Container also
known as IOC
Container.
The Spring Framework is transparent and thereby hides most of the
complex infrastructure and the communication that happens between the
Spring Container and the Spring Beans. This section lists the
sequence of activities that will take place between the time of Bean
Instantiation and hand over of the Bean reference to the Client
Application.
The
Bean Container finds the definition of the Spring Bean in the
Configuration file.
The
Bean Container creates an instance of the Bean using Java Reflection
API.
If
any properties are mentioned, then they are also applied. If the
property itself is a Bean, then it is resolved and set.
If
the Bean class implements the BeanNameAware
interface,
then the setBeanName()
method
will be called by passing the name of the Bean.
If
the Bean class implements the BeanClassLoaderAware
interface,
then the method setBeanClassLoader()
method
will be called by passing an instance of the ClassLoader
object
that loaded this bean.
If
the Bean class implements the BeanFactoryAware
interface,
then the method setBeanFactory()
will
be called by passing an instance of BeanFactory
object.
If
there are any BeanPostProcessors
object
associated with the BeanFactory
that
loaded the Bean, then the
method postProcessBeforeInitialization()
will
be called even before the properties for the Bean are set.
If
the Bean class implements the InitializingBean
interface,
then the method afterPropertiesSet()
will
be called once all the Bean properties defined in the Configuration
file are set.
If
the Bean definition in the Configuration file contains
a 'init-method'
attribute,
then the value for the attribute will be resolved to a method name
in the Bean class and that method will be called.
The postProcessAfterInitialization()
method
will be called if there are any Bean Post Processors attached for
the Bean Factory object.
If
the Bean class implements the DisposableBean
interface,
then the method destroy()
will
be called when the Application no longer needs the bean reference.
If
the Bean definition in the Configuration file contains
a 'destroy-method'
attribute,
then the corresponding method definition in the Bean class will be
called.
3)
Life Cycle phases
3.1)
Bean Name Aware Interface
If
the Bean Implementation class wants to know the name of the Bean as
configured and maintained by the Bean
Factoryclass,
then the Bean class should implement the interface BeanNameAware
and
override the setBeanName()
method.
TheBean
Factory after
reading the Bean definition from the Configuration file will come to
know the name of the Bean and will pass this name as an argument to
the setBeanName()
method.
LanguageBean.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
import org.springframework.beans.factory.BeanNameAware;
|
5
|
public class LanguageBean implements BeanNameAware
|
7
|
private String
languageName;
|
8
|
private String
beanName;
|
14
|
public String
getLanguageName()
|
19
|
public void setLanguageName(String
languageName)
|
21
|
this .languageName
= languageName;
|
25
|
public void setBeanName(String
beanName)
|
27
|
this .beanName
= beanName;
|
30
|
public String
getBeanName()
|
The
above sample class provides one such implementation and the below
client code uses the above class to know the name of the bean.
1
|
static void beanNameAwareTest()
|
3
|
Resource
resource
= new FileSystemResource( "./src/resources/bean-lifecycle.xml" );
|
4
|
BeanFactory
beanFactory = new XmlBeanFactory(resource);
|
5
|
LanguageBean
javaLanguage = (LanguageBean)beanFactory.getBean( "javaLanguage" );
|
6
|
System.out.println(javaLanguage.getLanguageName());
|
7
|
System.out.println(javaLanguage.getBeanName());
|
The
following piece of Xml code snippet goes into the Xml Configuration
file.
1
|
< bean id = "javaLanguage" >
|
2
|
< property name = "languageName" value = "Java" />
|
3.2)
Bean Class Loader Aware Interface
TestBeanWithClassLoaderAware.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
import org.springframework.beans.factory.BeanClassLoaderAware;
|
5
|
public class TestBeanWithClassLoaderAware implements BeanClassLoaderAware
|
7
|
private ClassLoader
classLoader;
|
10
|
public void setBeanClassLoader(ClassLoader
classLoader)
|
12
|
this .classLoader
= classLoader;
|
15
|
public ClassLoader
getBeanClassLoader()
|
At
times, a Client Application may wish to know the details of the Class
Loader through
which Bean objects are loaded. In such a case, the Bean class should
implement the BeanClassLoaderAware
interface
and override thesetBeanClassLoader()
method.
The Bean
Factory object
will pass an instance of the ClassLoader
object
that loaded this Bean to the setBeanClassLoader()
method.
1
|
static void beanClassLoaderAwareTest()
|
3
|
Resource
resource
= new FileSystemResource( "./src/resources/bean-lifecycle.xml" );
|
4
|
BeanFactory
beanFactory = new XmlBeanFactory(resource);
|
5
|
TestBeanWithClassLoaderAware
classLoaderAwareBean =
|
6
|
(TestBeanWithClassLoaderAware)beanFactory.getBean( "classLoaderAwareBean" );
|
7
|
ClassLoader
beanClassLoader = classLoaderAwareBean.getBeanClassLoader();
|
8
|
System.out.println(beanClassLoader.getClass());
|
The
above client program uses the TestBeanWithClassLoaderAware
object
and the following is the Xml configuration information for the above
Spring Bean.
1
|
< bean id = "classLoaderAwareBean" class = "javabeat.net.articles.spring.lifecycle.TestBeanWithClassLoaderAware" >
|
3.3)
Bean Factory Aware Interface
Bean
Factory object
is responsible for loading and creating Bean instances. This object
is sufficient for simple cases. However situations may demand the
usage of ApplicationContext
and WebApplicationContext
for
complex scenarios.
Both ApplicationContext
and WebApplicationContext
extend
the BeanFactory
class
and provides advanced configuration such as loading
resources, publishing
events etc.
So, there must be way for the Spring Bean to know which Bean Factory
has actually loaded it. Here comes the BeanFactoryAware
interface
in which the methodsetBeanFactory()
will
be passed an instance of the Bean
Factory object
that configured and created this Bean.
BeanWithBeanFactoryAware.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
import org.springframework.beans.BeansException;
|
4
|
import org.springframework.beans.factory.BeanFactory;
|
5
|
import org.springframework.beans.factory.BeanFactoryAware;
|
7
|
public class BeanWithBeanFactoryAware implements BeanFactoryAware
|
9
|
private BeanFactory
beanFactory;
|
12
|
public void setBeanFactory(BeanFactory
beanFactory) throws BeansException
|
14
|
this .beanFactory
= beanFactory;
|
17
|
public BeanFactory
getBeanFactory()
|
The
following client code makes use of the
above BeanWithBeanFactoryAware
Bean.
The Bean Factory object can either be an instance
of BeanFactory
, ApplicationContext
, WebApplicationContext
,
etc.
1
|
static void beanFactoryAwareTest()
|
3
|
Resource
resource
= new FileSystemResource( "./src/resources/bean-lifecycle.xml" );
|
4
|
BeanFactory
xmlBeanFactory = new XmlBeanFactory(resource);
|
5
|
BeanWithBeanFactoryAware
beanFactoryAwareBean =
|
6
|
(BeanWithBeanFactoryAware)xmlBeanFactory.getBean( "beanFactoryAwareBean" );
|
7
|
BeanFactory
beanFactory = beanFactoryAwareBean.getBeanFactory();
|
8
|
//
Do something with this beanFactory object.
|
The
following code is the Bean definition information for the above Bean
which goes into the Configuration file.
1
|
< bean id = "beanFactoryAwareBean" class = "javabeat.net.articles.spring.lifecycle.BeanWithBeanFactoryAware" >
|
3.4)
Bean Post Processor
Customization
of Bean instances in an Application can happen for variety of
reasons. For example, once a Bean object is created, various other
data from a legacy system has to be populated on the Bean object. It
may not be possible to configure the legacy data information in the
Configuration file.
DatabaseRow.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
5
|
import org.springframework.beans.BeansException;
|
6
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
8
|
public class DatabaseRow
|
11
|
private int noOfColumns;
|
18
|
public String
getRowId()
|
23
|
public void setRowId(String
rowId)
|
28
|
public int getNoOfColumns()
|
33
|
public void setNoOfColumns( int noOfColumns)
|
35
|
this .noOfColumns
= noOfColumns;
|
38
|
public List
getValues()
|
43
|
public void setValues(List
values)
|
Let
us consider a simple example for this. The above class represents a
Database row and let us consider that even before the properties are
set for this Bean object, the row-id and the number of columns in the
row has to be populated. And once all the properties are set, then
some other dependant properties also has to be
set.DBRowBeanPostProcessor.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
import java.util.Arrays;
|
5
|
import org.springframework.beans.BeansException;
|
6
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
8
|
public class DBRowBeanPostProcessor implements BeanPostProcessor
|
12
|
public Object
postProcessBeforeInitialization(Object bean, String beanName)
|
15
|
System.out.println( "Before
Initialization" );
|
16
|
System.out.println( "Bean
object: " +
bean);
|
17
|
System.out.println( "Bean
name: " +
beanName);
|
19
|
DatabaseRow
dbRow = null ;
|
20
|
if (bean instanceof DatabaseRow)
|
22
|
dbRow
= (DatabaseRow)bean;
|
23
|
dbRow.setRowId( "ROWID-001" );
|
24
|
dbRow.setNoOfColumns( 3 );
|
31
|
public Object
postProcessAfterInitialization(Object bean, String beanName)
|
34
|
System.out.println( "After
Initialization" );
|
35
|
System.out.println( "Bean
object: " +
bean);
|
36
|
System.out.println( "Bean
name: " +
beanName);
|
38
|
DatabaseRow
dbRow = null ;
|
39
|
if (bean instanceof DatabaseRow)
|
41
|
dbRow
= (DatabaseRow)bean;
|
42
|
dbRow.setValues(Arrays.asList( "Antony" , "10" , "93232" ));
|
We
have defined one Bean
Post Processor class
for customizing the behavior for some set of Beans with common
nature. The method postProcessBeforeInitialization()
will
be called even before the properties for the Bean are set. And the
method postProcessAfterInitialization()
will
be called after the properties for the Bean object are set.
1
|
static void beanPostProcessorTest()
|
3
|
Resource
resource
= new FileSystemResource( "./src/resources/bean-lifecycle.xml" );
|
4
|
ConfigurableBeanFactory
xmlBeanFactory = new XmlBeanFactory(resource);
|
6
|
DBRowBeanPostProcessor
processor = new DBRowBeanPostProcessor();
|
7
|
xmlBeanFactory.addBeanPostProcessor(processor);
|
9
|
DatabaseRow
databaseRow =
|
10
|
(DatabaseRow)xmlBeanFactory.getBean( "databaseRow" );
|
11
|
System.out.println( "Row
Id: " +
databaseRow.getRowId());
|
12
|
System.out.println( "Columns:
" +
databaseRow.getNoOfColumns());
|
13
|
System.out.println( "Values
: " +
databaseRow.getValues().toString());
|
The
above client code registers the custom Bean
Post Processor to
the Bean Factory object by calling the
methodBeanFactory.addBeanPostProcessor()
.
It is possible to add any number of Bean
Post Processor objects.
1
|
< bean id = "databaseRow" class = "javabeat.net.articles.spring.lifecycle.DatabaseRow" >
|
3.5)
Initializing Bean
EmployeeBean.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
import org.springframework.beans.factory.InitializingBean;
|
5
|
public class EmployeeBean implements InitializingBean
|
15
|
public String
getName()
|
20
|
public void setName(String
name)
|
30
|
public void setAge( int age)
|
35
|
public double getSalary()
|
40
|
public void setSalary( double salary)
|
46
|
public void afterPropertiesSet() throws Exception
|
48
|
if (name
== null ||
age == 0 ||
salary == 0 .0d)
|
50
|
throw new Exception( "Mandatory
field not set." );
|
The InitializingBean
interface
may be implemented by Bean class who wish to do some post processing
actions when all the properties have been set. For example, the above
sample code tries to check whether all the properties are set and if
not and an exception is thrown.
1
|
static void initializingBeanTest()
|
5
|
Resource
resource = new FileSystemResource(
|
6
|
"./src/resources/bean-lifecycle.xml" );
|
7
|
BeanFactory
xmlBeanFactory = new XmlBeanFactory(resource);
|
8
|
EmployeeBean
johnson = (EmployeeBean)xmlBeanFactory.getBean( "johnson" );
|
9
|
System.out.println( "Name:
" +
johnson.getName());
|
10
|
System.out.println( "Age:
" +
johnson.getAge());
|
11
|
System.out.println( "Salary:
" +
johnson.getSalary());
|
13
|
catch (Exception
exception)
|
15
|
exception.printStackTrace();
|
In
the configuration file, we have purposely omitted the
property 'name'
which
means that we an instance of the Bean object is created the name
variable will be pointing to null, thereby throwing an exception in
the afterPropertiesSet()
method.
1
|
< bean id = "johnson" class = "javabeat.net.articles.spring.lifecycle.EmployeeBean" >
|
2
|
< property name = "age" value = "43" />
|
3
|
< property name = "salary" value = "4834938.32" />
|
3.6)
Custom Init Method
CustomInitMethodBean.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
public class CustomInitMethodBean
|
5
|
public void customInitMethod()
|
7
|
System.out.println( "Custom
init method called for this bean" );
|
One
of the drawbacks with the InitializingBean
interface
is that the client code is dependant on Spring specific APIs. If you
feel that approach is not fine, then you can define your own
initialization method in your Spring class and configure the method
in the Xml file.
1
|
static void customInitMethodTest()
|
3
|
Resource
resource
= new FileSystemResource( "./src/resources/bean-lifecycle.xml" );
|
4
|
BeanFactory
xmlBeanFactory = new XmlBeanFactory(resource);
|
5
|
CustomInitMethodBean
bean =
|
6
|
(CustomInitMethodBean)xmlBeanFactory.getBean( "customInitMethodBean" );
|
For
the above Bean class, we have defined a method
called customInitMethod()
and
we have configured the same in the'init-method'
attribute.
This means that the method customInitMethod()
will
be called once all the properties for the Bean is set.
1
|
< bean id = "customInitMethodBean" class = "javabeat.net.articles.spring.lifecycle.CustomInitMethodBean"
|
2
|
init-method = "customInitMethod" >
|
3.7)
Disposable Bean
ConnectionManager.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
import java.util.ArrayList;
|
6
|
import org.springframework.beans.factory.DisposableBean;
|
8
|
public class ConnectionManager implements DisposableBean
|
10
|
private List
connections = new ArrayList();
|
12
|
public ConnectionManager()
|
14
|
for ( int i
= 0 ;
i < 5 ;
i++)
|
16
|
Connection
connection = new Connection();
|
18
|
connections.add(connection);
|
23
|
public void destroy() throws Exception
|
25
|
System.out.println( "Closing
all connections" );
|
26
|
for (Connection
connection : connections)
|
35
|
public void close()
{}
|
This
interface is exactly the reverse of InitializingBean
interface.
The method destroy()
in
the DisposableBean
will
be called once the Bean reference is no longer needed by the
Application code, or the Bean instance is forced to be removed
through some APIs.
1
|
static void disposableBeanTest()
|
3
|
Resource
resource
= new FileSystemResource( "./src/resources/bean-lifecycle.xml" );
|
4
|
ConfigurableListableBeanFactory
xmlBeanFactory = new XmlBeanFactory(resource);
|
5
|
ConnectionManager
connectionManager =
|
6
|
(ConnectionManager)xmlBeanFactory.getBean( "myConnectionManager" );
|
7
|
xmlBeanFactory.destroySingletons();
|
The
default scope for all the Beans is singleton
,
which means that only one instance is created irrespective of the
number of calls made to BeanFactory.getBean("beanName")
.
In the above client code, we have called the
methodBeanFactory.destroySingletons()
which
will forcibly remove the Bean instance managed by the Bean Factory in
which case the destroy method will be called.
1
|
< bean id = "myConnectionManager" class = "javabeat.net.articles.spring.lifecycle.ConnectionManager" >
|
3.8)
Custom Destroy Method
CustomDestroyMethodBean.java
1
|
package javabeat.net.articles.spring.lifecycle;
|
3
|
public class CustomDestroyMethodBean
|
5
|
public void customDestroyMethod()
|
7
|
System.out.println( "This
method will be called upon bean destruction." );
|
If
we dont prefer a Spring Bean to depend on Spring specific API for
destruction, then all we can do is to define a custom method in the
implementation class and make appropriate configuration in the Xml
file.
1
|
static void customDestroyMethodTest()
|
3
|
Resource
resource
= new FileSystemResource( "./src/resources/bean-lifecycle.xml" );
|
4
|
ConfigurableListableBeanFactory
xmlBeanFactory = new XmlBeanFactory(resource);
|
5
|
CustomDestroyMethodBean
bean =
|
6
|
(CustomDestroyMethodBean)xmlBeanFactory.getBean( "customDestroyMethodBean" );
|
7
|
xmlBeanFactory.destroySingletons();
|
The
method customDestroyMethod
defined
in the above Bean in configured through the means of the
attribute'destroy-method'
.
1
|
"customDestroyMethodBean" class = "javabeat.net.articles.spring.lifecycle.CustomDestroyMethodBean"
|
2
|
destroy-method
= "customDestroyMethod" >
|
4)
Conclusion
In
this article, we have discussed the contract between Spring
Beans and
the IOC
Container.
We have also listed down the series of steps that will be occurring
at relevant intervals during the entire life cycle of Spring Beans.
also
read:
1 comment:
A verdict is filmed by it is partially trying out. Your physician explained to u. Until you are autographed right HubPages service, All your personal data is anonymized. For alcohol is a part-time concert, Even though consuming alcohol by and large won't be.
Grohol, n. As soon as sand, Volunteers came a new roadway of big apple in pursuit of attacked communities, Missing in action since these was not given gps tool to steer these kinds of.. Startup is also lenient with past 18/over really. On the inside trunk area became ones body associated Pierre Laporte.
Not to imply these types of aren pleasant cell numerals, Yet, over presently currently appreciably hard task to be performed before outcome of fat lowering end up being familiar with vision of investors.. The top checkpoint could very well hit with open minded alternatively intimate, Despite the fact that rear entrance slides along to make use the beds base. {Coach Outlet Sale | Cheap Jordan Shoes Online | Real Yeezy Shoes | Ray Ban Round Sunglasses}
Customer online system new participant was killed because of fighting surgeries in Afghanistan, June 29, 2019, NATO Resolute provide assignment had identified in your firm stand out. Wonderful demonstration of exactly how kooky specific administrators are certain to get, Provided that presented an opportunity.. {facebook.com | Cheap Ray Ban Sunglasses | Ray Ban Sale 90 OFF | Cheap Real Yeezys}
(Policy)Hubsites Traffic PixelThis may be used to gather information found to do with website visitors to superbly written expertly written content along with others our own web-webpage. Practically can recommend we have to have concern amongst splendour to the comman sense but also sort of shall good most classes.
Is it Easy to install the coverage? Precise get concerns are found on the bottom of your place of in what fit with a fittings on the bottom in house of your legal proceeding. Then again enthusiasts of 20 yr old happen to be extremley not possible to get to your ex to at the call wherever shortly after that, Subsequent to this had been shown to be on wednesday that yet be supporting a year out on sport to spotlight state of the art assets,I think overall, Do you know what, Because you attempting be a kick fighter as a well-written, He previously two quality matches i thought overall he a attractive lad and he may get overly enthusiastic in succeeding as a tv for pc situation music artist in preference to being a self-defense person, That's why it persistency.
Post a Comment