Back to feed
ASH avatar
ASH

2026. 5. 5.·v1·

Spring의 DI는 Nest와 어떻게 다를까?

spring과 nest의 의존성주입 차이점

Nest에서는 특정 Provider를 DI 하려면 DI를 받으려는 모듈 컨텍스트의 의존성 컨테이너에 해당 Provider가 토큰으로 관리되고 있어야하고, 생성자에서 토큰을 명시해 매칭되는 Provider를 주입받는다.

Spring은 Nest와 본질적으로는 비슷하지만 약간 느낌이 다르다.
Nest처럼 모듈 컨텍스트에서 토큰으로 의존성을 찾는 것이 아닌 ApplicationContext(Spring Bean 컨테이너)에서 타입/이름 기준으로 Bean을 찾고 주입한다.

여기서 ApplicationContext가 의존성 컨테이너 역할을 하는데, 여기에 @Component, @Service, @Repository, @Controller, @Configuration, @Bean과 같은 데코레이터로 등록된 객체들이 Bean으로 들어가게 된다.
Nest처럼 모듈별 컨텍스트가 아닌 전역적인 Bean 컨테이너를 중심으로 동작한다고 보면 이해하기 쉽다.

토큰 대신 타입?

Nest에선 보통 provider를 등록할 때, 클래스 자체를 토큰으로 넣어주거나, useClass와 함께 문자열 토큰 또는 심볼 토큰을 사용한다.

ts
providers: [
	UserService,
	MyService,
	{
		provide: 'USER_REPO',
		useClass: UserRepository,
	}
]

provider를 주입할 때는 이런식으로 토큰을 명시해준다. (문자열, 심볼 토큰으로 관리하는 경우에)

ts
constructor(@Inject('USER_REPO) private readonly repo:UserRepository){
} // 문자열,심볼 토큰

constructor(private readonly myService: MyService) // 클래스 토큰

스프링은 기본적으로 타입 기반 주입이 메인이다.

kotlin
class UserService(
	private val userRepository: UserRepository
)

이렇게 하면 Nest에서 클래스 토큰을 사용하는 provider를 주입받을 때처럼 UserRepository라는 타입만으로 Bean을 찾을 수 있다.

그렇다고 스프링에서 타입으로만 의존성 주입이 가능한 것은 아니다.
스프링 Bean은 내부적으로 bean name을 가지기때문이다.
예를 들어

kotlin
@Service
class UserService {}

이건 기본적으로 bean name이 userService로 잡힌다.

그리고 @Bean데코레이터를 사용하면 이름을 부여하는 것도 가능하다.

kotlin
@Configuration
class AppConfig {
	@Bean
	fun objectMapper() = ObjectMapper()
}

이 경우 bean name은 objectMapper가 된다.

즉 스프링 Bean은 타입/이름을 둘 다 가질 수 있지만 일반적인 DI는 타입을 기반으로 한다는 것을 알아두자.

Related

0
Comments

Join the thread

Leave feedback, ask for clarification, or keep a focused discussion attached to this article.

0 comments
No comments yet. Start the first thread for this article.
Current user avatar
Styling with Markdown is supported