In this tutorial, you will learn to use Spring @Import and @ImportResource annotations to import configurations from java-config class and XML configurations respectively. These annotations work well with @Configuration annotations.
Make sure you have a clear understanding of the ways to do Dependency Injections in Spring and the other related concepts.
- Check the related article on Inversion of Control and Dependency Injection in Spring.
- Read the article on Spring @PropertySource to read property files
- Similar annotation, Classpath Scanning using @ComponentScan
1. Overview:
As you know, the @Configuration classes represent the @Bean and other Spring IoC configurations. You can also use XML based bean configurations in a Spring application. Spring allows you to use multiple @Configuration classes and combine (import) them using @Import annotation. Similarly, you need to use @ImportResource annotation if you want to mix XML and Java configurations
- The @Import annotation is used to import multiple classes annotated with @Configuration.
- The @ImportResource annotation indicates one or more XML based bean definition files to be imported.
The configurations loaded through @ImportResource takes precedence over @Bean. This makes sense to use external bean configuration files to override the code level configs.
2. Example of @Import and @ImportResource annotations
Let us think of a sample store which processes both offline orders (pickup) and online orders (delivery order). We have two order processor classes, OfflineOrderProcessor
and OnlineOrderProcessor
. Offline order processor bean is registered with java configuration class OfflineStoreConfig
, but the Online order processor bean is registered using XML config online-store-config.xml
.
To try this example, create a maven project and add the latest version of Spring core and Spring context dependencies.
... <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> </dependencies> ...
1. Offline store processor and config class
package com.jbd.sc.items.offline; public class OfflineOrderProcessor { public void processOrder(String item) { System.out.println("Offline order processed: " + item); } }
package com.jbd.sc.items.offline; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class OfflineStoreConfig { @Bean public OfflineOrderProcessor offlineOrderProcessor() { return new OfflineOrderProcessor(); } }
2. Next, create the Online order processor and XML config
package com.jbd.sc.items.online; public class OnlineOrderProcessor { public void processOrder(String item) { System.out.println("Online order processed: " + item); } }
<?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="onlineOrderProcessor" scope="singleton" class="com.jbd.sc.items.online.OnlineOrderProcessor"/> </beans>
3. Use @Import and @ImportResource
Now we will use @Import on the final configuration class to import the OfflineStoreConfig
and the @ImportResource
to include the xml configuration resources/online-store-config.xml
.
package com.jbd.sc.importannotation; import com.jbd.sc.items.offline.OfflineOrderProcessor; import com.jbd.sc.items.offline.OfflineStoreConfig; import com.jbd.sc.items.online.OnlineOrderProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportResource; @Configuration @Import(OfflineStoreConfig.class) @ImportResource("classpath:online-store-config.xml") public class ApplicationConfig { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class); context.getBean(OfflineOrderProcessor.class).processOrder("Book"); context.getBean(OnlineOrderProcessor.class).processOrder("Mobile Phone"); } }
Output
Offline order processed: Book Online order processed: Mobile Phone
3. Aggregating configurations
You can group multiple configurations in @Import and @ImportResource annotations. In the previous example, we have used only single class and single xml config files inside these annotations. But you can pass more than one class and xml bean definition files as parameter.
@Configuration @Import({ SavingAccountConfig.class, LoanAccountConfig.class }) class AccountConfiguration { }
@Configuration @ImportResource({ "saving-account-config.xml", "loan-account-config.xml" }) class AccountConfiguration { }
4. Conclusion:
This is a small topic, I hope you have got a clear idea on Spring @Import and @ImportResource annotations and how multiple bean configurations can be aggregated in a single config file. You can use the same annotations on a Junit test class as well. I recommend you to use the @ComponentScan annotation wherever possible instead of these.
Leave A Comment