1. Introduction
The @Import annotation is used in Spring to import Java configuration classes, regular component classes, or even bean definition classes into the current application context. It allows for modularizing your application configuration and managing bean definitions across multiple configuration files or components.
2. Basic Definition
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
- The
@Importannotation is placed on a@Configurationclass (or a@SpringBootApplicationclass). - It accepts one or more classes as arguments, and Spring will import their beans into the application context.
3. Use Cases of @Import
| Use Case | Description |
| Modular configuration | Organize configurations into multiple classes |
| Enable third-party configurations | Import configs from libraries or external modules |
| Avoid component scanning | Manually register beans instead of using @ComponentScan |
| Conditional bean loading | Use in combination with @Conditional, @Profile, or @ConditionalOnProperty |
4. Example: Importing Configuration Classes
Suppose you have two configuration classes:
DatabaseConfig.java
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource(); // example
}
}
SecurityConfig.java
@Configuration
public class SecurityConfig {
@Bean
public SecurityManager securityManager() {
return new SecurityManager();
}
}
MainApplication.java
@SpringBootApplication
@Import({DatabaseConfig.class, SecurityConfig.class})
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
This tells Spring to include both DatabaseConfig and SecurityConfig when building the application context.
5. Importing Component Classes (Non-Configuration)
You can also use @Import to bring in regular component classes that are not marked with @Component.
UtilityService.java
public class UtilityService {
public String getMessage() {
return "Hello from UtilityService";
}
}
AppConfig.java
@Configuration
@Import(UtilityService.class)
public class AppConfig {
}
Now, UtilityService will be available as a Spring-managed bean even though it is not annotated with @Component.
6. Using @Import with @Enable... Annotations
Many Spring annotations like @EnableAsync, @EnableScheduling, @EnableTransactionManagement, etc., internally use @Import to register configuration classes.
@EnableAsync // internally uses @Import(AsyncConfigurationSelector.class)
@Configuration
public class AppConfig {
}
7. ImportSelector and DeferredImportSelector
You can write custom logic to determine which classes to import at runtime using:
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[] { "com.example.MyBeanConfig" };
}
}
Using the selector:
@Configuration
@Import(MyImportSelector.class)
public class AppConfig {
}
DeferredImportSelector is a special interface. Used for deferring the import decision until all @Configuration classes are processed.
8. Comparison with @ComponentScan and @Bean
| Feature | @Import | @ComponentScan | @Bean |
| Registers class directly? | Yes | No, scans package for @Component classes | No |
| Requires annotations in target class? | No | Yes (@Component, etc.) | No |
| Programmatic control? | Yes (with ImportSelector) | Limited | Yes |
