Spring @Import Annotation Example

In this section we will learn about @Import Annotation.


When we run a Spring application, the packages are scanned. Beans are created from @Component, @Service, @Repository and @Configuration classes.

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:

mvn spring-boot:run

Console Output:
Inside SMSNotificationService Constructor
Inside EmailNotificationService Constructor
Sending Email Notification


Download Source Code

More related topics,

Spring Web Annotations


Spring Core Annotations

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete