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.

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 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.

pom.xml
... 
  <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

The OfflineOrderProcessor class represents a component responsible for processing offline orders. It contains a method processOrder that takes an item as input and prints a message indicating that the offline order has been processed for that item.

OfflineOrderProcessor.java
package com.jbd.sc.items.offline;

public class OfflineOrderProcessor {
  public void processOrder(String item) {
    System.out.println("Offline order processed: " + item);
  }
}

It defines a bean named offlineOrderProcessor of type OfflineOrderProcessor using the @Bean annotation.

OfflineStoreConfig.java
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

The OnlineOrderProcessor class represents a component responsible for processing online orders. Similar to the OfflineOrderProcessor, it contains a method processOrder that takes an item as input and prints a message indicating that the online order has been processed for that item.

OnlineOrderProcessor.java
package com.jbd.sc.items.online;

public class OnlineOrderProcessor {

  public void processOrder(String item) {
    System.out.println("Online order processed: " + item);
  }
}

This XML configuration file defines a Spring bean named onlineOrderProcessor with the class com.jbd.sc.items.online.OnlineOrderProcessor. The scope attribute is set to singleton, indicating that Spring will create and manage a single instance of the OnlineOrderProcessor class throughout the application context.

XML
<?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.

The ApplicationConfig class demonstrates how to configure a Spring application using a combination of Java-based configuration and XML-based configuration, and how to interact with beans defined in the application context to perform certain tasks, such as processing offline and online orders.

ApplicationConfig.java
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");

  }
}

In the above ApplicationConfig class:

  1. @Configuration: This annotation marks the class as a configuration class, indicating that it contains bean definitions and other configuration settings for the Spring application context.
  2. @Import(OfflineStoreConfig.class): This annotation imports the bean definitions from the OfflineStoreConfig class. It allows us to include the bean configurations defined in OfflineStoreConfig into the current configuration class.
  3. @ImportResource("classpath:online-store-config.xml"): This annotation imports bean definitions from an XML configuration file named online-store-config.xml located in the classpath. It allows us to include XML-based bean configurations into the current configuration class.
  4. context.getBean(OfflineOrderProcessor.class).processOrder("Book"): This line retrieves the bean of type OfflineOrderProcessor from the application context and calls the processOrder method with the argument “Book”.
  5. context.getBean(OnlineOrderProcessor.class).processOrder("Mobile Phone"): This line retrieves the bean of type OnlineOrderProcessor from the application context and calls the processOrder method with the argument “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.

AccountConfiguration.java
@Configuration
@Import({ SavingAccountConfig.class, LoanAccountConfig.class })
class AccountConfiguration {
  //extra stuff goes here
}
  • The AccountConfiguration class is annotated with @Configuration, indicating that it contains bean definitions and configuration settings for the Spring application context.
  • The @Import annotation is used to import bean definitions from multiple Java-based configuration classes (SavingAccountConfig and LoanAccountConfig). This allows the bean definitions from these classes to be included in the current configuration class (AccountConfiguration).
  • By passing an array of classes to the @Import annotation, you can import bean definitions from multiple configuration classes simultaneously.

Similarly, you can group multiple XML bean definition files using the @ImportResource annotation – AccountConfiguration class imports bean definitions from two XML configuration files (“saving-account-config.xml”, “loan-account-config.xml”) located in the classpath.

AccountConfiguration.java
@Configuration
@ImportResource({ "saving-account-config.xml", "loan-account-config.xml" })
class AccountConfiguration { 
  //other stuff goes here
}

4. Conclusion:

  • The @Import and @ImportResource annotations in Spring provide powerful mechanisms for consolidating and organizing bean definitions and configuration settings in your application.
  • By using @Import, you can group multiple Java-based configuration classes into a single configuration class, simplifying the management of bean definitions and promoting modularity and reusability in your Spring application.
  • Similarly, @ImportResource allows you to import bean definitions from multiple XML configuration files, enabling you to integrate legacy XML-based configurations with modern Java-based configurations seamlessly.
  • Whether you’re working with Java-based or XML-based configurations, leveraging these annotations allows you to create more organized, maintainable, and flexible Spring applications.

By |Last Updated: April 2nd, 2024|Categories: Spring Framework|