클래스 초기화 시 의존성을 주입하는 것이 필요한 이유
이전 시간까지 우리는 String 타입이나 Int 같은 간단한 타입의 Bean만 만들었다. 하지만, 실제 애플리케이션을 만들 때는 클래스들이 다른 클래스에 의존하기 때문에 주입을 받아야 하는 상황이 많이 발생한다. 즉, 초기화를 위해 의존성을 주입 받아야 하는 상황이 많이 발생한다.
예를 들어 다음과 같은 UserCreator 클래스가 있다고 해보자.
class UserCreator(private val repository: UserRepository) {
fun createUserWithRandomId(user: String) {
val id = UUID.randomUUID().toString()
repository.createUser(id, user)
println("[User Creation Success] User $user id: $id")
}
}
이 UserCreator 클래스는 실행을 위해 UserRepository를 필요로 하며, 이 UserRepository는 다음과 같은 인터페이스이고 구현체 InMemoryUserRepository를 가진다.
interface UserRepository {
fun createUser(id: String, user: String)
}
class InMemoryUserRepository(): UserRepository {
override fun createUser(id: String, user: String) {
println("User $user created with id: $id in InMemoryUserRepository")
}
}
그러면 이 UserRepository와 UserCreator을 Bean으로 만들려면, 다음과 같이 작성해야 되는데, UserCreator을 생성하기 위해서는 UserRepository가 필요하기 때문에 오류가 발생한다.
이 문제를 해결하기 위해서는 UserCreator 생성 시 UserRepository를 주입 받아야 한다. 지금부터 그 방법을 알아보자.
클래스 초기화 시 의존성을 주입 하기
의존성을 주입하는 방법은 간단하다. UserCreator Bean을 만들 때 UserRepository를 userCreator 함수의 인자로 넘기면 된다. 다음 코드에서는 userCreator 함수의 인자로 UserRepository 객체를 넘겼다.
@Configuration
class UserContainerConfiguration {
@Bean
fun userRepository(): UserRepository {
return InMemoryUserRepository()
}
@Bean
fun userCreator(repository: UserRepository): UserCreator {
return UserCreator(repository)
}
}
그러면 이제 UserCreator Bean은 생성될 때 InMemoryUserRepository를 주입 받는다.
한 번 다음 코드를 실행해, UserCreator가 제대로 생성됐는지 확인해보자.
fun main(args: Array<String>) {
val context = AnnotationConfigApplicationContext(UserContainerConfiguration::class.java)
context.getBean(UserCreator::class.java).createUserWithRandomId("세영")
}
이 코드의 실행 결과는 다음과 같다.
UserCreator 객체의 createUserWithRandomId가 호출됐을 때, InMemoryUserRepository의 createUser가 호출된 것을 볼 수 있다.
Code: GitHub
도움이 되셨다면 ⭐️를 눌러주세요!