In this guide we will see how to use the Spring @Import annotation, importing multiple configuration classes, and we will see difference between @Import vs @ComponentScan.
@Import annotation in Spring allows you to load bean definitions from one or more another @Configuration
files or Components. You might not want to configure all the beans in one configuration file. Using @Import we can split the configurations across multiple configuration files for modularising, that makes our code more cleaner and maintainable.
1. Creating Configuration classes
First let’s create configuration classes and then import them to another configurations. Here we are creating FishConfig and BirdConfig configuration files, they having GoldFish, Guppy, Salmon, Eagle, Ostrich, Peacock bean definitions.
Creating Configuration classes:
@Configuration public class FishConfig { @Bean public GoldFish goldFish() { return new GoldFish(); } @Bean public Guppy guppy() { return new Guppy(); } @Bean public Salmon salmon() { return new Salmon(); } }
@Configuration public class BirdConfig { @Bean public Eagle eagle() { return new Eagle(); } @Bean public Ostrich ostrich() { return new Ostrich(); } @Bean public Peacock peacock() { return new Peacock(); } }
2. Using @Import annotation
Now, Let’s import the FishConfig and BirdConfig files into another configuration called ImportBeansConfig. @Import annotation allows grouping/importing multiple configurations also.
In following example we are defining ExampleBean and Sample beans for testing imported configurations.
@Configuration @Import({FishConfig.class, BirdConfig.class}) public class ImportBeansConfig { @Bean public ExampleBean exampleBean() { return new ExampleBean(); } @Bean public SampleBean sampleBean() { return new SampleBean(); } }
public class ExampleBean { @Autowired private Salmon salmon; @Autowired private Guppy guppy; @Autowired private Peacock peacock; public void printObjects() { System.out.println("---------- Print ExampleBean Objects ----------"); System.out.println(salmon); System.out.println(guppy); System.out.println(peacock); } }
public class SampleBean { @Autowired private GoldFish goldFish; @Autowired private Eagle eagle; @Autowired private Ostrich ostrich; public void printObjects() { System.out.println("---------- Print SampleBean Objects ----------"); System.out.println(goldFish); System.out.println(eagle); System.out.println(ostrich); } }
Testing @Import:
public class ImportAnnotationConfigDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(ImportBeansConfig.class); ExampleBean exampleBean = ctxt.getBean(ExampleBean.class); SampleBean sampleBean = ctxt.getBean(SampleBean.class); exampleBean.printObjects(); sampleBean.printObjects(); } }
Output Results:
---------- Print ExampleBean Objects ---------- Salmon Guppy Peacock ---------- Print SampleBean Objects ---------- GoldFish Eagle Ostrich
3. Importing Components
@Import annotation allowed to import specific component into other configuration. We can import group/multiple components. Let’s see example, in the following example ExampleComponent importing into ImportComponentsConfig which defined bean called ComponentsTestBean.
@Configuration @Import(ExampleComponent.class) public class ImportComponentsConfig { @Bean public ComponentsTestBean componentsTestBean() { return new ComponentsTestBean(); } }
Let’s see the existed Spring components/beans in application context.
public class ImportComponetsConfigDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(ImportComponentsConfig.class); String[] components = ctxt.getBeanDefinitionNames(); for (String bean : components) System.out.println(bean); } }
If you run above program, you will see following output and you can notice ExampleComponent in available beans in application context.
importComponentsConfig com.javabydeveloper.spring.config.importannotation.component.ExampleComponent componentsTestBean ..... ......other spring internal beans
4. Spring @Import vs @ComponentScan
@ComponentScan: It tells Spring which packages/components to scan and find using configuration.
@Import: It tells Spring which configurations/components import into another configuration.
4.1. We can achieve same results by using both annotations, but conceptually they use for different purpose. Let’s take look into an example, suppose that we have crocodiles and snakes packages and we configured beans within those using @ComponentScan.
@Configuration @ComponentScan(basePackages = "com.javabydeveloper.spring.bean.animal.reptiles.snakes") public class SnakesConfig { }
@Configuration @ComponentScan(basePackages = "com.javabydeveloper.spring.bean.animal.reptiles.crocodles") public class CrocodleConfig { }
Suppose that, now you want another configuration Reptiles that you need both snakes and crocodiles. As both SnakesConfig and CrocodleConfig available, we need to import them into ReptilesConfig instead of scanning them again.
@Configuration @Import({CrocodleConfig.class, SnakesConfig.class}) public class ReptilesImportConfig { }
4.2. @ComponentScan annotation has more control on detecting components by using filters/package/classes/annotations.
5. Conclusion
In this tutorial we have learned about Spring @Import annotation and Conceptual difference between @Import vs @ComponentScan. In simple, @ComponentScan is used to detect components in configuration, @Import is used to import one or multiple configurations into another configuration.
You can get source code at our GtHub repository.
6. References
Other Related Tutorials:
- Spring @Autowired
- Spring @Lazy
- Spring Boot XML Configuration
- Spring Injecting Collection
- Spring @Order
- Spring @Primary
- Spring Component Scanning
- Spring @ComponentScan Filter Types