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 hasabstract="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 fromabstractAuthor
. - 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.
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.
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 extendsBaseConfig
. It inherits the bean configurations defined inBaseConfig
.- Additionally,
ChildConfig
defines its own bean configuration using the@Bean
annotation, which adds to the configurations inherited fromBaseConfig
.
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.