🚀 Master Modular Spring JavaConfig!
Subscribe to Ram N Java for clean architectural patterns, Spring framework tutorials, and code walkthroughs!
🔔 Subscribe to Ram N JavaMastering Spring JavaConfig with the @Import Annotation
As enterprise Spring applications grow in scale, consolidating all configuration beans into a monolithic class quickly creates technical debt and maintainability challenges. Spring provides the @Import annotation as the standard mechanism to organize, separate, and import modular @Configuration classes cleanly, keeping configuration files modular, focused, and test-friendly.
How @Import Simplifies Spring Configuration
The @Import annotation functions as the pure Java equivalent of the traditional <import resource="..."/> element in XML configuration:
- Granular Configuration: Distinct domain layers (such as service configurations, persistence settings, or security filters) are isolated in separate classes marked with
@Configuration. - Centralized Composition: A root or primary configuration class pulls in these discrete configuration classes using
@Import({ConfigA.class, ConfigB.class}). - Single Entry Point: When booting up
AnnotationConfigApplicationContext, developers only need to pass the central class. Spring automatically registers and coordinates all declared beans across the imported classes.
Step-by-Step Implementation Flow
- Define Sub-Configurations: Build feature-specific configuration classes (e.g.,
ConfigAprovidingBeanA, andConfigBprovidingBeanB). - Aggregate with @Import: In your central configuration class (such as
AppConfig), annotate the class with@Configurationand@Import({ConfigA.class, ConfigB.class}). - Bootstrap ApplicationContext: Instantiate the Spring container by passing only
AppConfig.classintoAnnotationConfigApplicationContext. - Verify Bean Availability: Both
BeanAandBeanBare instantiated, wired, and accessible from the single application context seamlessly.
Major Architectural Benefits
- Enhanced Maintainability: Keeps configuration files concise, domain-driven, and easy to navigate.
- Isolated Unit & Integration Testing: Enables test setups to selectively load only relevant configuration modules rather than the full application context.
- Explicit Dependencies: Provides clear visibility into configuration dependencies directly through standard Java imports and type references.
Recommended Next Videos
Broaden your Spring JavaConfig and architecture expertise with these related tutorials from our channel:
Click here to watch on Youtube:
https://www.youtube.com/watch?v=zGTO57LGOtI&list=UUhwKlOVR041tngjerWxVccw
Click the below Image to Enlarge:
| Spring JavaConfig @Import example | @Import Annotation in Spring JavaConfig | Spring Tutorial |
| Spring JavaConfig @Import example | @Import Annotation in Spring JavaConfig | Spring Tutorial |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0%20http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ram.core</groupId>
<artifactId>SpringDemo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringDemo</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0%20http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ram.core</groupId>
<artifactId>SpringDemo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringDemo</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
Employee.java
package com.ram.model;
public class Employee
{
private int id;
private String name;
public Employee(int id, String name)
{
System.out.println("Employee(int id, String name) constructor "
+ "is called by the Spring container");
this.id = id;
this.name = name;
}
public void displayEmployeeDetails()
{
System.out.println("Employee [id=" + id + ", name=" + name + "]");
}
}
public class Employee
{
private int id;
private String name;
public Employee(int id, String name)
{
System.out.println("Employee(int id, String name) constructor "
+ "is called by the Spring container");
this.id = id;
this.name = name;
}
public void displayEmployeeDetails()
{
System.out.println("Employee [id=" + id + ", name=" + name + "]");
}
}
EmployeeConfig.java
package com.ram.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ram.model.Employee;
/**
* Annotate with @Configuration to tell Spring that this is the core
* Spring configuration file, and define bean via @Bean.
*/
@Configuration
public class EmployeeConfig
{
@Bean(name = "employee")
public Employee getEmployee()
{
return new Employee(36,"Peter");
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ram.model.Employee;
/**
* Annotate with @Configuration to tell Spring that this is the core
* Spring configuration file, and define bean via @Bean.
*/
@Configuration
public class EmployeeConfig
{
@Bean(name = "employee")
public Employee getEmployee()
{
return new Employee(36,"Peter");
}
}
ApplicationBeans.java
package com.ram.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Annotate with @Configuration to tell Spring that this is the core
* Spring configuration file, and define bean via @Bean.
*/
@Configuration
@Import({EmployeeConfig.class})
public class ApplicationBeans
{
}
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Annotate with @Configuration to tell Spring that this is the core
* Spring configuration file, and define bean via @Bean.
*/
@Configuration
@Import({EmployeeConfig.class})
public class ApplicationBeans
{
}
App.java
package com.ram.core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.ram.config.ApplicationBeans;
import com.ram.model.Employee;
public class App
{
public static void main(String[] args)
{
ApplicationContext context = new AnnotationConfigApplicationContext(
ApplicationBeans.class);
System.out.println("---------------------------------------");
Employee employee = (Employee) context.getBean("employee");
System.out.println(
"Got employee object from the ApplicationContext(Spring Container)");
employee.displayEmployeeDetails();
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.ram.config.ApplicationBeans;
import com.ram.model.Employee;
public class App
{
public static void main(String[] args)
{
ApplicationContext context = new AnnotationConfigApplicationContext(
ApplicationBeans.class);
System.out.println("---------------------------------------");
Employee employee = (Employee) context.getBean("employee");
System.out.println(
"Got employee object from the ApplicationContext(Spring Container)");
employee.displayEmployeeDetails();
}
}
Output
Oct 06, 2018 8:30:01 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5f4da5c3: startup date [Sat Oct 06 08:30:01 IST 2018]; root of context hierarchy
Employee(int id, String name) constructor is called by the Spring container
---------------------------------------
Got employee object from the ApplicationContext(Spring Container)
Employee [id=36, name=Peter]
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5f4da5c3: startup date [Sat Oct 06 08:30:01 IST 2018]; root of context hierarchy
Employee(int id, String name) constructor is called by the Spring container
---------------------------------------
Got employee object from the ApplicationContext(Spring Container)
Employee [id=36, name=Peter]
Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_JavaConfig_import.zip?attredirects=0&d=1
Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_JavaConfig_import
Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/864d48b49c31c0a6d41770bb5dba6b0893945b87/Spring_2018/SpringDemo_JavaConfig_import/?at=master
See also:






