In Java, we inherit one object using the abstract keyword, Spring also supports us to do the same thing in itself. This tutorial will show you how to use bean inheritance in Spring.
OK, first we need to have a Maven project to work. I created the Maven project as follows:
In particular, the Spring framework dependency is as follows:
1 2 3 4 5 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.1.RELEASE</version> </dependency> |
Clazz class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.huongdanjava.springinheritance; public class Clazz { private String name; private String schoolName; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } } |
Application class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.huongdanjava.springinheritance; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Clazz clazzA = (Clazz) context.getBean("clazzA"); System.out.println("\n" + clazzA.getSchoolName()); } } |
To be able to use inheritance, at least the beans that are declared in the Spring container must have a common feature. So in the Clazz class above, I declare a field that is common to all bean fields, schoolName.
In Spring container, I initialize as follows:
1 2 3 4 5 6 7 8 9 10 11 |
<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"> <bean id="clazzA" class="com.huongdanjava.springinheritance.Clazz"> </bean> <bean id="clazzB" class="com.huongdanjava.springinheritance.Clazz"> </bean> </beans> |
OK, now I’m going to declare a common bean for all Clazz objects with the same field schoolName “Tam Quan Nam” as follows:
1 2 3 |
<bean id="generalClazz" class="com.huongdanjava.springinheritance.Clazz"> <property name="schoolName" value="Tam Quan Nam" /> </bean> |
In order for the bean clazzA and bean clazzB to use the common bean, we need to declare the parent attribute with the id of the generic bean, in the declaration of the bean clazzA and bean clazzB, as follows:
1 2 3 4 5 |
<bean id="clazzA" class="com.huongdanjava.springinheritance.Clazz" parent="generalClazz"> </bean> <bean id="clazzB" class="com.huongdanjava.springinheritance.Clazz" parent="generalClazz"> </bean> |
Now if you run the program, you will see the results as follows:
As you can see, although we do not declare the schoolName field for the clazzA bean, the clazzA bean still has the field name because it is inherited from the general beanClazz.
It should also be added that in this case our general beanClazz is also initialized in Spring’s container and we can retrieve it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.huongdanjava.springinheritance; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Clazz generalClazz = (Clazz) context.getBean("generalClazz"); System.out.println("\n" + generalClazz.getSchoolName()); } } |
Result:
If you want it to be just an abstract as defined in Java, which means that it cannot be initialized in Spring’s container, we can declare the abstract = “true”:
1 2 3 |
<bean id="generalClazz" class="com.huongdanjava.springinheritance.Clazz" abstract="true"> <property name="schoolName" value="Tam Quan Nam" /> </bean |
In this case, if you run the code above, will encounter the following error:
1 2 3 4 5 6 7 8 9 10 |
Nov 29, 2017 2:00:17 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@45ff54e6: startup date [Wed Nov 29 02:00:17 ICT 2017]; root of context hierarchy Nov 29, 2017 2:00:18 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [spring.xml] Exception in thread "main" org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'generalClazz': Bean definition is abstract at org.springframework.beans.factory.support.AbstractBeanFactory.checkMergedBeanDefinition(AbstractBeanFactory.java:1319) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083) at com.huongdanjava.springinheritance.Application.main(Application.java:11) |