September 10, 2022

Spring Boot and Dependency Injection

Dependency injection in Spring Boot is no different from the dependency injection in Spring framework. You can use any of the standard Spring Framework techniques to define your beans and their injected dependencies. SpringBoot suggests using @ComponentScan (to find your beans) and using @Autowired (to do constructor injection).

Spring Boot Dependency Injection Example

We’ll create a simple Spring Boot stand alone application to show Spring Boot dependency injection.

For a stand alone application you need to add dependency for spring-boot-starter apart from the dependency for spring-boot-starter-parent.

Maven Dependencies
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.knpcode</groupId>
  <artifactId>SpringBootProject</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>
Bean Classes

In the example there is a class to place order called Order and purchase can be done from a store for which there is a class RetailStore. Order class has a dependency on Store.

public interface OrderService {
  public void buyItems();
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderServiceImpl implements OrderService {
  private IStore store;
  @Autowired
  public OrderServiceImpl(IStore store){
    this.store = store;
  }

  public void buyItems() {
    store.doPurchase();
  }
}
public interface IStore {
  public void doPurchase();
}
@Service
public class RetailStore implements IStore {
  public void doPurchase() {
    System.out.println("Doing purchase from Retail Store");
  }
}

One of the best practice for dependency injection is to code to interfaces that is why there are interfaces and then their concrete implementations. The idea is to depend on abstractions not on concrete implementations to make dependencies less rigid.

Also classes are annotated with @Service annotation which makes these classes eligible for component scanning. @Autowired annotation is used to inject dependency through constructor injection.

Application class with main method

To bootstrap this spring boot example following class annotated with @SpringBootApplication is used.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import com.knpcode.springbootproject.service.OrderService;
import com.knpcode.springbootproject.service.OrderServiceImpl;

@SpringBootApplication
public class FirstSpringBootApp {
  public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(FirstSpringBootApp.class, args);
    OrderService orderService = ctx.getBean(OrderServiceImpl.class);
    orderService.buyItems();
  }
}

@SpringBootApplication is a convenience annotation that adds all of the following annotations-

  1. @Configuration annotation tags the class as a source of bean definitions for the application context.
  2. @EnableAutoConfiguration tells Spring Boot to enable auto configuration. Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example starter spring-boot-starter-web adds Tomcat and Spring MVC so the auto-configuration assumes that you are developing a web application and sets up Spring accordingly which includes setting up a DispatcherServlet.
  3. @ComponentScan tells Spring to look recursively for other components, configurations and services inside this package and register them. All of your application components (@Component, @Service, @Repository, @Controller etc.) are automatically registered as Spring Beans.

On running this Application class as Java application you will get the output as

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

2019-08-11 11:48:12.473  INFO 13036 --- [           main] c.k.s.FirstSpringBootApp                 : Starting FirstSpringBootApp on user with PID 13036 (started by Anshu in F:\knpcode\Spring WorkSpace\SpringBootProject)
2019-08-11 11:48:12.476  INFO 13036 --- [           main] c.k.s.FirstSpringBootApp                 : No active profile set, falling back to default profiles: default
2019-08-11 11:48:13.414  INFO 13036 --- [           main] c.k.s.FirstSpringBootApp                 : Started FirstSpringBootApp in 1.478 seconds (JVM running for 2.515)
Doing purchase from Retail Store

That's all for the topic Spring Boot and Dependency Injection. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment