About Spring Dependency Injection using Java, Kotlin

Overview

This time, I will summarize how to write Spring DI using Java and Kotlin respectively. The environment is Java 1.8, Kotlin 1.2.31, Spring Boot 2.0.0.RELEASE, Spring 5.0.3.RELEASE.

About DI in Spring

I will omit the detailed explanation about DI. For more information, see Spring Official References Please read.

There are two main types of DI in Spring, "** Setter injection " and " Constructor injection **". If you search online, you will find the word "Field injection", but it is a term that does not appear in the official reference. For the sake of explanation, this article also uses the term Field injection, but it is essentially the same as Setter injection. The Spring team also recommends Constructor injection because it can guarantee that the dependent objects are non-null and immutable. On the other hand, Setter injection should be used for limited purposes such as resetting dependencies.

In the following, we will summarize how to write each of these "Field injection", "Setter injection", and "Constructor injection" in Java and Kotlin.

Field Injection First, let's talk about Field Injection in Java. Field Injection is expressed by writing like ↓.

@Component
class SampleComponent{

  @Autowired
  public HogeService hogeService;

  @Autowired
  public FugaService fugaService;

  public void hogehoge(){
    hogeService.hoge();
  }

  public void fugafuga(){
    fugaService.fuga();
  }
}

Next, in Kotlin, write as ↓.

@Component
class SampleComponent{
  @Autowired
  lateinit var hogeService: HogeService
  
  @Autowired
  lateinit var fugaService: FugaService

  /*The following methods are omitted*/
}

Kotlin field variables must be initialized at the time of declaration, so if you want to DI, you need to explicitly indicate that they are lazy initialization with the lateinit modifier. Also, in Field Injection, the value is assigned later, so variable declaration using val is not possible.

Setter Injection Next, if you write setter injection in java, it will be code like ↓.

@Component
class SampleComponent{
 
  private HogeService hogeService;
  
  private FugaService fugaService;

  @Autowired
  public void setHoge(HogeService hogeService){
    this.hogeService = hogeService;
  }

  @Autowired
  public void setFuga(FugaService fugaService){
    this.fugaService = fugaService;
  }

  /*The following methods are omitted*/
}

Similarly, if you write a setter injection in Kotlin, you will get code like ↓.

@Component
class SampleComponent{

  private var hogeService: HogeService? = null
    @Autowired
    set(hogeService){
      this.hogeService = hogeService
    }

  private var fugaService: FugaService? = null
    @Autowired
    set(fugaService){
      this.fugaService = fugaService
    }

  /*The following methods are omitted*/

/*You can also write like ↓
  private lateinit var hogeService: HogeService
  
  private lateinit var fugaService: FugaService
  
  @Autowired
  fun setHogeService(hogeService: HogeService){
    this.hogeService = hogeService
  }

  @Autowired
  fun setFugaService(fugaService: FugaService){
    this.fugaService = fugaService
  }
*/
}

In kotlin, getters are automatically generated when a field is declared with val, and getters and setters are automatically generated when a field is declared with var. Therefore, like Field injection, variables are declared with var. Furthermore, since it is necessary to customize the processing of the setter, it is necessary to write set () as shown in the code above. You can also write it in much the same way as Java, as I wrote in the comments.

Constructor Injection Finally, if you write Constructor Injection in Java, the code will look like ↓.

@Component 
class SampleComponent{

  private final HogeService hogeService;

  private final FugaService fugaService;

  @Autowired
  SampleComponent(HogeService hogeService, FugaService fugaService){
    this.hogeService = hogeService;
    this.fugaService = fugaService;
  }

  /*The following methods are omitted*/
}

If you only have one constructor, you can omit @Autowired.

@Component 
class SampleComponent{

  private final HogeService hogeService;

  private final FugaService fugaService;

  //If there is only one constructor@Autowired can be omitted
  SampleComponent(HogeService hogeService, FugaService fugaService){
    this.hogeService = hogeService;
    this.fugaService = fugaService;
  }
  /*The following methods are omitted*/
}

Furthermore, if you use Lombok to automatically generate a constructor, you can express Constructor Injection without declaring the constructor.

@Component 
@AllArgsConstructor
class SampleComponent{

  private final HogeService hogeService;

  private final FugaService fugaService;

  //It is automatically generated by Lombok, so you don't have to write a constructor.

  /*The following methods are omitted*/
}

Next, if you express Constructor Injection in Kotlin, it will be the code of ↓.

@Component
class SampleComponent(
  private val hogeService: HogeService,
  private val fugaService: FugaService
){
  /*The following methods are omitted*/
}

In Kotlin, there is a grammar called primary constructor, and by writing like ↑, the constructor is automatically generated at compile time. This allows you to represent the Constructor Injection without the Lombok annotations.

reference

Recommended Posts

About Spring Dependency Injection using Java, Kotlin
[Java] [Spring] Spring Boot Dependency injection mysterious hamarineta
Using Mapper with Java (Spring)
About Kotlin
About Spring ③
Spring Java
[Spring] Obfuscate specific fields using annotations [Java]
A story about a Spring Boot project written in Java that supports Kotlin
About Java interface
[Java] About Java 12 features
[Java] About arrays
About Spring AOP
Something about java
Where about java
About Java features
About spring AOP
About Java threads
[Java] About interface
About Java class
About Java arrays
About java inheritance
About interface, java interface
[Java] Spring DI ③
About List [Java]
About java var
About Java literals
About Java commands
Create a portfolio app using Java and Spring Boot
How to set Dependency Injection (DI) for Spring Boot
[Java] How to omit spring constructor injection with Lombok
About synchronized and Reentrant Lock (Java & Kotlin implementation example)
About Java log output
About Java functional interface
Sorting using java comparator
Java, about 2D arrays
About class division (Java)
About Spring Security authentication
About [Java] [StreamAPI] allMatch ()
About Java StringBuilder class
[Java] About Singleton Class
About Java method binding
About DI of Spring ①
[Java] About anonymous classes
About method splitting (Java)
About Spring AOP Pointcut
Scraping practice using Java ②
[Java Silver] About initialization
About DI of Spring ②
About Java Array List
About Java Polymorphism super ()
[Java, Kotlin] Type Variance
About inheritance (Java Silver)
About Java String class
About Java access modifiers
Scraping practice using Java ①
About Java lambda expressions
About Java entry points
About Java 10 Docker support
Personal summary about Java
[Java] About enum type
Dagger2 --Android Dependency Injection