In this article, we will look into spring’s default-lazy-init
and lazy-init
attributes. We will come to know about how the attributes influence the instantiation of the bean. default-lazy-init
is the default attribute which will be specified in the beans
element. One can override it using lazy-int
attribute at bean/code> level.
Dependencies
Add the following dependencies:
spring-core
spring-context
spring-beans
pom.xml:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javarticles.jdbc.datasource</groupId> <artifactId>springdatasource</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> </dependencies> <properties> <spring.version>3.2.3.RELEASE</spring.version> </properties> </project>
Default behavior of default-lazy-init
Let’s first look into the default behavior of default-lazy-init
which means what will be the behavior if the attribute is not present? Will it be lazily loaded or eagerly. The default behavior is eager loading.
noDefaultLazyInitContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-init-method="myInit"> <bean id="testBean" class="com.javarticles.spring.TestBean"> <constructor-arg type="java.lang.String" value="A" /> </bean> </beans>
Our TestBean
has myInit()
method will be invoked after the bean is instantiated. We also have a static variable isInitialized
which will let us know whether it is instantiated.
TestBean:
package com.javarticles.spring; public class TestBean { private TestBean innerBean; private String value; public static boolean isInitialized; public TestBean(){isInitialized = true;} public TestBean(String value) { this(); this.value = value; } public String getValue() { return value; } public TestBean getInnerBean() { return innerBean; } public void setValue(String value) { this.value = value; } public void myDestroy() { System.out.println("myDestroy called for TestBean(" + value + ")"); } public void myInit() { System.out.println("myInit called for TestBean(" + value + ")"); } public void setInnerBean(TestBean innerBean) { this.innerBean = innerBean; } public String toString() { return "TestBean: value[" + value + "]"; } }
Let’s load the context file and verify the TestBean.isInitialized
to know whether TestBean
is instantiated.
LazyInitExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class LazyInitExample { public static void main(String[] args) { printBeanInitStatus("default-lazy-init is not set: ", "noDefaultLazyInitContext.xml"); } private static void printBeanInitStatus(String useCase, String contextXml) { printBeanInitStatus(useCase, contextXml, false); } private static void printBeanInitStatus(String useCase, String contextXml, boolean getBean) { TestBean.isInitialized = false; System.out.println(useCase); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( contextXml); try { System.out.println("Is TestBean Initialized: " + TestBean.isInitialized); if (getBean) { System.out.println("Bean is created only when context.getBean is called"); System.out.println(context.getBean("testBean")); } } finally { context.close(); } } }
You can see from the output, it is instantiated. This will help us know during loading phase itself in case our bean has some issue.
Output:
default-lazy-init is not set: myInit called for TestBean(A) Is TestBean Initialized: true
default-lazy-init set to true
Since default-lazy-init
is set to true, TestBean
shouldn’t be created during the loading phase. It should be instantiated lazily when we call context.getBean("testBean")
defLazyInitTrueContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-init-method="myInit" default-lazy-init="true"> <bean id="testBean" class="com.javarticles.spring.TestBean"> <constructor-arg type="java.lang.String" value="A" /> </bean> </beans>
LazyInitExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class LazyInitExample { public static void main(String[] args) { printBeanInitStatus("default-lazy-init is not set: ", "noDefaultLazyInitContext.xml"); printBeanInitStatus("default-lazy-init is set to true: ", "defLazyInitTrueContext.xml", true); } private static void printBeanInitStatus(String useCase, String contextXml) { printBeanInitStatus(useCase, contextXml, false); } private static void printBeanInitStatus(String useCase, String contextXml, boolean getBean) { TestBean.isInitialized = false; System.out.println(useCase); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( contextXml); try { System.out.println("Is TestBean Initialized: " + TestBean.isInitialized); if (getBean) { System.out.println("Bean is created only when context.getBean is called"); System.out.println(context.getBean("testBean")); } } finally { context.close(); } } }
Output:
default-lazy-init is not set: myInit called for TestBean(A) Is TestBean Initialized: true default-lazy-init is set to true: Is TestBean Initialized: false Bean is created only when context.getBean is called myInit called for TestBean(A) TestBean: value[A]
Override lazy-init
overrideLazyInitTrueContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-init-method="myInit" default-lazy-init="true"> <bean id="testBean" class="com.javarticles.spring.TestBean" lazy-init="false"> <constructor-arg type="java.lang.String" value="A" /> </bean> </beans>
LazyInitExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class LazyInitExample { public static void main(String[] args) { printBeanInitStatus("default-lazy-init is not set: ", "noDefaultLazyInitContext.xml"); printBeanInitStatus("default-lazy-init is set to true: ", "defLazyInitTrueContext.xml", true); printBeanInitStatus("Override default-lazy-init, set lazy-init to true: ", "overrideLazyInitTrueContext.xml"); } private static void printBeanInitStatus(String useCase, String contextXml) { printBeanInitStatus(useCase, contextXml, false); } private static void printBeanInitStatus(String useCase, String contextXml, boolean getBean) { TestBean.isInitialized = false; System.out.println(useCase); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( contextXml); try { System.out.println("Is TestBean Initialized: " + TestBean.isInitialized); if (getBean) { System.out.println("Bean is created only when context.getBean is called"); System.out.println(context.getBean("testBean")); } } finally { context.close(); } } }
Output:
default-lazy-init is not set: myInit called for TestBean(A) Is TestBean Initialized: true default-lazy-init is set to true: Is TestBean Initialized: false Bean is created only when context.getBean is called myInit called for TestBean(A) TestBean: value[A] Override default-lazy-init, set lazy-init to true: myInit called for TestBean(A) Is TestBean Initialized: true
Download the source code
This was an example about Spring’s lazy-init attribute. You can download the source code here: springLazyInitExample.zip