In Spring Framework, bean definition inheritance (bean configuration inheritance) is a valuable time-saving feature we must learn. As you know, a bean definition is nothing but the configuration for the Spring IoC container to create our bean as per the details. Refer to the article Inversion of Control and Dependency Injection in Spring, if you need to understand the basics of the bean definition.

These bean definitions can contain a lot of useful configurations like constructor arguments, property values, initialization methods and so on.

  • Using the Bean definition Inheritance, a child bean definition inherits the configuration from a Parent configuration.
  • The Child definition can also override values and add additional configurations as needed.
  • It is up to the programmers to whether use this in your projects, but at least it can save a lot of repetitive configs in my opinion.

Example of bean config inheritance

When you use XML-based configuration as shown below, use the parent attribute to specify the parent bean configuration.

  • The bean with id abstractAuthor is the abstract configuration as it has abstract="true". Spring will not create an instance of an abstract bean.
  • On the other hand, the bean with id="bookAuthor" is the child bean configuration that inherits the bean configs from abstractAuthor.
  • The parent="abstractAuthor" indicates the parent bean.
<?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">

<bean id="abstractAuthor" abstract="true"
      class="basic.ioc.config.inheritance.Author">
  <property name="name" value="author"/>
  <property name="age" value="18"/>
</bean>

<bean id="bookAuthor" parent="abstractAuthor"
      class="basic.ioc.config.inheritance.BookAuthor">
  <!-- override - age -->
  <property name="age" value="20"/>
  <property name="bookName" value="The Book"/>
</bean>

</beans>
package basic.ioc.config.inheritance;

import java.util.StringJoiner;

public abstract class Author {

  private String name;
  private Integer age;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  @Override
  public String toString() {
    return new StringJoiner(", ", Author.class.getSimpleName() + "[", "]")
        .add("name='" + name + "'")
        .add("age=" + age)
        .toString();
  }
}
package basic.ioc.config.inheritance;

import java.util.StringJoiner;

public class BookAuthor extends Author {

  private String bookName;

  public String getBookName() {
    return bookName;
  }

  public void setBookName(String bookName) {
    this.bookName = bookName;
  }

  @Override
  public String toString() {
    return new StringJoiner(", ", BookAuthor.class.getSimpleName() + "[", "]")
        .add(super.toString())
        .toString();
  }
}
public class TestConfigInheritance {

  @Test
  public void testBeanConfigInheritance(){

  ApplicationContext aContext
      = new ClassPathXmlApplicationContext("bean-config.xml");

  Author author = aContext.getBean(Author.class);
  BookAuthor bookAuthor = aContext.getBean(BookAuthor.class);
  System.out.println(author);
  System.out.println(bookAuthor);
  }
}

Output

BookAuthor[Author[name='author', age=20]]
BookAuthor[Author[name='author', age=20]]

The output prints the BookAuthor twice, as the Author is declared as an abstract class.

Conclusion

This is a small concept but can be very useful in time. If you are using Java-based IoC configuration with annotations like @Configuration and @Bean, create separate reusable functions and use it inside the @Bean configurations. Share your feedback on this article in the comments below. The code example is available to download from GitHub repo.