Just like the OOPS concept of inheritance
is used in object oriented language where child class can inherit attributes and methods of a parent class same way in
Spring framework child bean can inherit configuration data from a parent definition. In this post we’ll see how bean
definition inheritance works in Spring.
Bean definition inheritance in Spring
A bean definition can contain a lot of configuration information, including constructor arguments, property values,
and container-specific information, such as the initialization method, a static factory method name, and so on. A child
bean definition can inherit that configuration information from a parent bean rather than defining everything again.
The child definition can override some values or add others as needed.
How does bean definition inheritance work
Parent bean definition that is inherited in the child bean definition is specified using parent attribute
of the <bean> element. For example in the following configuration parent bean definition is inherited by empBean
using the parent attribute and it inherits the property company from parent bean definition and adds name property of
its own.
<bean id="baseEmpBean" class="com.knpcode.Employee">
<property name="company" value="XYZ"/>
</bean>
<bean id="empBean" parent="baseEmpBean">
<property name="name" value="Jack" />
</bean>
In the configuration you can see that the child bean definition doesn’t specify a bean class.
A child bean definition doesn't need to specify a bean class it can use the bean class from the parent definition. Though
child bean definition can also override bean class, if it does then the child bean class must be compatible with the parent
(that is, it must accept the parent’s property values). For example-
<bean id="parentBean" class="com.knpcode.TestBean">
<property name="name" value="parent"/>
<property name="mode" value="inherit"/>
</bean>
<bean id="childBean" class="org.springframework.beans.DerivedTestBean" parent="inheritedTestBean" >
<property name="name" value="override"/>
<!-- mode property value will be inherited from parent -->
</bean>
Spring Bean definition inheritance Example
In the example there is a bean class Employee with properties empId, empName, company, dept. In the parent definition value
for company property is assigned which is inherited by the child bean definition.
public class Employee {
int empId;
String empName;
String company;
String dept;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
@Override
public String toString() {
return "Id= " + getEmpId() + " Name= " +
getEmpName() + " Dept= "+ getDept()
+ " Company= " + getCompany();
}
}
Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="baseEmpBean" class="com.knpcode.springproject.model.Employee">
<property name="company" value="XYZ"/>
</bean>
<bean id="empBean" parent="baseEmpBean">
<property name="empId" value="1" />
<property name="empName" value="Jack" />
<property name="dept" value="HR" />
</bean>
</beans>
You can use the following class with main method to read the configuration and access the beans.
public class App {
public static void main( String[] args ){
// create context using configuration
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");
Employee emp = context.getBean("empBean", Employee.class);
System.out.println(emp);
context.close();
}
}
Output
20:09:24.009 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'baseEmpBean'
20:09:24.140 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'empBean'
Id= 1 Name= Jack Dept= HR Company= XYZ
Abstract attribute in Spring Bean definition inheritance
If you want to restrict instantiation of parent bean then you can mark it as abstract="true" to do that.
Abstract attribute in Spring bean definition
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- acts as a template -->
<bean id="baseEmpBean" abstract="true" class="com.knpcode.springproject.model.Employee">
<property name="company" value="XYZ"/>
</bean>
<bean id="empBean" parent="baseEmpBean" >
<property name="empId" value="1" />
<property name="empName" value="Jack" />
<property name="dept" value="HR" />
</bean>
</beans>
With parent marked as abstract trying to access parent bean results in an error.
Exception in thread "main" org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'baseEmpBean': Bean definition is abstract
at org.springframework.beans.factory.support.AbstractBeanFactory.checkMergedBeanDefinition(AbstractBeanFactory.java:1335)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1111)
at com.knpcode.springproject.App.main(App.java:14)
Parent bean as Template in Spring bean inheritance
By marking parent bean definition as abstract=”true” and not specifying a class too you can use parent only as a pure
template bean definition that serves as a parent definition for child definitions.
Note that if the parent definition does not specify a class, explicitly marking the parent bean definition as abstract
is required.
Template bean definition example
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- acts as a template -->
<bean id="baseEmpBean" abstract="true">
<property name="company" value="XYZ"/>
</bean>
<bean id="empBean" parent="baseEmpBean" class="com.knpcode.springproject.model.Employee">
<property name="empId" value="1" />
<property name="empName" value="Jack" />
<property name="dept" value="HR" />
</bean>
</beans>
That's all for the topic Spring Bean Definition Inheritance. If something is missing or you have something
to share about the topic please write a comment.
You may also like