Bean definition inheritance

Bean definition inheritance means that you have lot of bean definition in the bean configuration file and you have something that is common across lots of bean. There is a common setter value that has to be initialized across multiple beans and only then bean definition inheritance can be used.

You can have one parent bean that contains all of these common definitions inside it, and then you can inherit all the common bean definitions across the other bean. This parent bean, which has all the common definitions, can be a bean in itself. This parent bean can be made into abstract bean definitions, so there are no beans created for it, and all it does is for the purpose of templating a bean definition.

From a parent bean definition, a child bean definition inherits configuration data and can override or add values, as required. In an XML-based configuration file, a child bean definition is indicated using a parent attribute that specifies the parent bean as the value of this attribute. Refer to the following table for clarity:

Beans

Description

ParentBean

<bean id="pBean" class="ParentBean">

ChildBean

<bean id="cBean" class="ChildBean" parent="pBean">

ParentBean and ChildBean are explained as follows:

  • ParentBean: This is a parent bean that is used as a template to create other beans. It would be referred to in the XML file with id="pBean".
  • ChildBean: This is a child bean that inherits from the parent bean defined earlier. The parent="pBean" specifies that this bean is inheriting the properties of the ParentBean bean.

The child bean must accept the parent bean's property values. The child bean definition inherits constructor argument values and property values from the parent bean definition. The child bean definition overrides the initialization method setting and destroys method setting from the parent bean definition.

Spring bean definition inheritance is not related with the Java class inheritance. A parent bean is defined as a template and child beans can inherit the required configuration from this parent bean.

Now, the following example illustrates bean definition inheritance.

In the Employee.java class, you'll find the following code:

package org.packt.Spring.chapter2.beaninheritance;

public class Employee {

   private int employeeId;
   private String employeeName;
   private String country;

   public void setEmployeeId(int employeeId) {
          this.employeeId = employeeId;
   }

   public void setEmployeeName(String employeeName) {
          this.employeeName = employeeName;
   }

   public void setCountry(String country) {
         this.country = country;
   }

   @Override
   public String toString() {
         return "Employee ID: " + employeeId + " Name: " + employeeName
                     + " Country: " + country;
   }

}

In the preceding code snippet, the Employee class contains properties named employeeName, employeeId, country, and their corresponding setter method. This class has also overridden the toString() method.

The Spring bean configuration file, beans.xml, where we defined the indianEmployee bean as a parent bean with the country property and its value. Next, an employeeBean bean has been defined as the child bean of indianEmployee using the parent="indianEmployee" parent attribute. The child bean inherits country properties from the parent bean and introduces two more properties, employeeId and employeeName.

In the beans.xml file, you'll find the following code:

...
    <bean id="indianEmployee" class="org.packt.Spring.chapter2.beaninheritance.Employee">
                  <property name="country" value="India"></property>
   </bean>

   <bean id="employeeBean" parent="indianEmployee">
          <property name="employeeId" value="1065"></property>
          <property name="employeeName" value="Ravi Kant Soni"></property>
   </bean>
...

In the PayrollSystem.java class, you'll find the following code:

package org.packt.Spring.chapter2.beaninheritance;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PayrollSystem {

   public static void main(String[] args) {

         ApplicationContext context = new ClassPathXmlApplicationContext(
                      "beans.xml");

         // using 'employeeBean'
         Employee employeeA = (Employee) context.getBean("employeeBean");
         System.out.println(employeeA);

         // using 'indianEmployee'
         Employee employeeB = (Employee) context.getBean("indianEmployee");
         System.out.println(employeeB);
   }
}

When we run the PayrollSystem class, the result will be as follows:

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1c4f0f8: startup date [Sun Jan 25 14:31:50 IST 2015]; root of context hierarchy
Jan 25, 2015 2:31:51 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Employee ID: 1065 Name: Ravi Kant Soni Country: India
Employee ID: 0 Name: null Country: India

Here, the indianEmployee bean is able to instantiate. In the indianEmployee bean, we have only set the value for the country property, so other fields get the null value. In the employeeBean, we have set only two properties, which are employeeId and employeeName, and the country property is inherited from the indianEmployee bean, so all the fields get their value for employeeBean.

Inheritance with abstract

Inheritance with abstract helps in creating a bean definition as a template, which cannot be instantiated and serves as a parent definition for child definitions. While defining a bean definition as a template, you should specify only the abstract attribute with the value true, for example, abstract="true".

In the beans.xml file, you'll find the following code:

...
<bean id="indianEmployee" class="org.packt.Spring.chapter2.beaninheritance.Employee"
          abstract="true">
          <property name="country" value="India"></property>
   </bean>

   <bean id="employeeBean" parent="indianEmployee">
         <property name="employeeId" value="1065"></property>
         <property name="employeeName" value="Ravi Kant Soni"></property>
   </bean>
...

The parent bean indianEmployee cannot be instantiated on its own because it is explicitly marked as abstract. When a bean definition is abstract, that bean definition is served as a pure template bean definition and used as a parent definition for child definitions. So, while running the PayrollSystem class, the following code snippet will result in an error message on the console:

...
          // using 'indianEmployee'
          Employee employeeB = (Employee) context.getBean("indianEmployee");
         System.out.println(employeeB);
...

Since the indianEmployee bean is a pure template, if you try to instantiate it, you will encounter the following error message:

org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'indianEmployee': Bean definition is abstract
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.91.37