Spring @Import Annotation Example
In this section we will learn about @Import Annotation.
Scanning takes place using the @ComponentScan annotation. It is contained inside the @SpringBootApplication annotation, with which the main class of the application is annotated.
All classes that are in the same package as the class with the @ComponentScan (that is, with the @SpringBootApplication) as well as in the subpackages of this package are scanned.
If you generate a Spring Boot project on the https://start.spring.io site, you can see: the main class with the annotation with the @SpringBootApplication is in the root package. This means that by default all classes that are below are scanned.
That is, the Main Application can be in the com.knf.dev.demo package, but not in the java folder without the package.
Correct Structure:
The EmailNotificationService and SMSNotificationService classes are components—they're annotated with @Service. Since they lie in the structure of packages below the main class, they are successfully scanned, and beans are created on their basis.
Let's try to move EmailNotificationService to another package, which is not in the subpackage relative to MainApplication, but parallel to it.
Here the email.service package is parallel to the com.knf.dev.demo package, com.knf.dev.demo contains main class.
Now the EmailNotificationService is not scanned, and the bean is not created. This can be seen if we try to extract the EmailNotificationService type beans from the ApplicationContext.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
EmailNotificationService emailNotificationService =
context.getBean(EmailNotificationService.class);
emailNotificationService.sendEmailNotification();
context.close();
}
}
An error appears in the console:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'email.service.EmailNotificationService' available
The error can be corrected using @Import annotation.
We can use @Import to add classes to the list of those that you are scanning, even if they are in a different package.
To scan the EmailNotificationService, next to the @SpringBootApplication add an annotation @Import.
@SpringBootApplication
@Import(EmailNotificationService.class)
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
EmailNotificationService emailNotificationService =
context.getBean(EmailNotificationService.class);
emailNotificationService.sendEmailNotification();
context.close();
}
}
We can pass an array of classes to @Import.
The following example creates a Spring Boot application which uses @Import annotation.
Project Directory
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-import-annotation-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-import-annotation-example</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
EmailNotificationService.java
package email.service;
import org.springframework.stereotype.Service;
@Service
public class EmailNotificationService {
public EmailNotificationService() {
System.out.println("Inside EmailNotificationService Constructor");
}
public void sendEmailNotification()
{
System.out.println("Sending Email Notification");
}
}
SMSNotificationService.java
package com.knf.dev.demo.service;
import org.springframework.stereotype.Service;
@Service
public class SMSNotificationService {
public SMSNotificationService() {
System.out.println("Inside SMSNotificationService Constructor");
}
public void sendSmsNotification()
{
System.out.println("Sending SMS Notification");
}
}
Run the application - Application.java
package com.knf.dev.demo;
import email.service.EmailNotificationService;
import com.knf.dev.demo.service.SMSNotificationService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(EmailNotificationService.class)
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
EmailNotificationService emailNotificationService =
context.getBean(EmailNotificationService.class);
emailNotificationService.sendEmailNotification();
context.close();
}
}
Application is the entry point that sets up the Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning.
Let's run this Spring boot application from either IntelliJ IDEA IDE by right click - Run 'Application.main()'Or you can use the below maven command to run:
package com.knf.dev.demo;
import email.service.EmailNotificationService;
import com.knf.dev.demo.service.SMSNotificationService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(EmailNotificationService.class)
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
EmailNotificationService emailNotificationService =
context.getBean(EmailNotificationService.class);
emailNotificationService.sendEmailNotification();
context.close();
}
}
Application is the entry point that sets up the Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning.
mvn spring-boot:run
Inside SMSNotificationService Constructor
Inside EmailNotificationService Constructor
Sending Email Notification