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.

1. Bean config inheritance using XML

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
<?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>
Author.java
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();
  }
}
BookAuthor.java
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();
  }
}
Junit Test case
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.

2. Spring Bean inheritance using annotations

In Java-based IoC configuration with annotations like @Configuration and @Bean, bean configuration inheritance can be achieved using inheritance in classes. Let’s create an example to illustrate this:

Suppose we have a base configuration class BaseConfig that defines common bean configurations, and a child configuration class ChildConfig that inherits from BaseConfig and adds or overrides specific bean configurations.

Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BaseConfig {
    
    @Bean
    public SomeBean someBean() {
        // Define common bean configuration
        return new SomeBean();
    }
}

@Configuration
public class ChildConfig extends BaseConfig {

    @Bean
    public AnotherBean anotherBean() {
        // Define additional bean configuration specific to ChildConfig
        return new AnotherBean();
    }
}
  • BaseConfig is a configuration class annotated with @Configuration that defines a common bean configuration using the @Bean annotation.
  • ChildConfig is another configuration class annotated with @Configuration that extends BaseConfig. It inherits the bean configurations defined in BaseConfig.
  • Additionally, ChildConfig defines its own bean configuration using the @Bean annotation, which adds to the configurations inherited from BaseConfig.

With this setup, when the Spring application context is initialized, beans defined in both BaseConfig and ChildConfig will be registered in the application context. The bean configurations defined in BaseConfig will be inherited by ChildConfig, and any additional or overridden configurations in ChildConfig will also be registered.

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. This approach promotes code reuse, maintains separation of concerns, and provides a clear and structured way to organize bean configurations in Spring applications.


By |Last Updated: April 1st, 2024|Categories: Spring Framework|