본문 바로가기
👨‍💻 프로그래밍/Java, Kotlin, Spring

Spring에서 같은 type의 Bean 구분하는 방법

by 개발자 진개미 2023. 6. 6.
반응형

 

Spring의 가장 핵심적인 기능은 객체의 수명주기를 개발자가 관리하지 않고 Spring에서 관리해 주는 겁니다. 보통 이를 제어의 역전 (IoC)이라고 부르는데요. 객체의 수명주기를 개발자가 제어하던게 역전되서, Spring에서 관리해 준다는 의미입니다.

Spring에서 관리되는 객체Bean이라고 부릅니다. 일반적으로 객체를 쓸 때와 같이, SpringBean도 같은 타입의 Bean이 여러개 있을 수 있습니다. 스프링에서 이 Bean들을 어떻게 구분하고, 적절한 Bean을 어떻게 가져다 쓸 수 있는지 정리했습니다.


@Qualifier

@Configuration
public class ObjectMapperConfig {

    @Bean
    public ObjectMapper mapper1() {
        return new ObjectMapper();
    }

    @Bean
    public ObjectMapper mapper2() {
        return new ObjectMapper();
    }

}

위와 같이 2개의 ObjectMapperBean으로 등록하면, SpringDI를 통해 ObjectMapper를 가져다 쓸 때 어떤 ObjectMapper를 써야 할지 모르게 됩니다. 

@Qualifier("mapper1")
@Bean
public ObjectMapper mapper1() {
    return new ObjectMapper();
}

이때, @Qualifier를 써서 BeanID를 지정해 줄 수 있습니다.

@Autowired
public Example(@Qualifier("mapper1") ObjectMapper objectMapper) {
    this.objectMapper = objectMapper;
}

그럼 위와 같이 Bean ID를 써서 정확히 어떤 Bean이 필요한지 명시할 수 있습니다.


  • Bean을 정의할 때, @Qualifier를 쓰지 않으면 method 이름이 자동으로 Bean의 id가 됩니다.
  • 마찬가지로, DI를 할 때 @Qualifier를 쓰지 않으면 property의 이름을 자동으로 원하는 Bean의 id로 간주합니다.
  • 당연히 해당 type의 Bean이 1개 밖에 없으면 이름을 어떻게 짓든, @Qualifier가 없어도 문제 없이 동작합니다.

@Primary

기본적으로 @Qualifier만 있어도 Bean을 구별하는데 문제는 없지만, 대부분의 상황에서는 같은 Bean을 쓰고, 일부 특수 상황에서만 다른 Bean을 쓰는 상황에서는 일일히 @Qualifier를 쓰거나, 이름을 통일하는게 귀찮을 수 있습니다. 그럴때는 @Primary로 Bean 1개를 지정해 주면, 애매한 상황에서는 이 @Primary로 지정된 Bean을 쓰게 되서 코드량이 줄어들게 됩니다.

@Configuration
public class ObjectMapperConfig {

    @Primary
    @Bean
    public ObjectMapper objectMapper1() {
        return new ObjectMapper();
    }

    @Bean
    public ObjectMapper objectMapper2() {
        return new ObjectMapper();
    }

}

@Resource

@Resource는 정확히는 Bean들을 구별하기 위해서 있는건 아니고, @Autowired과 비슷하게 DI를 위해 있습니다. 차이점은 크게 2가지가 있습니다.

  1. @AutowiredSpring에서만 쓸 수 있고, @ResourceJava에 속해 있기 때문에 Spring이 아니라도 쓸 수 있습니다.
  2. @Autowiredtype을 기반으로 Bean을 찾고, 같은 typebean이 여러개면 @Qualifier를 통해 Bean ID를 명시해야 합니다. @Resource는 기본적으로 Bean ID를 사용해 찾고, Bean ID가 없으면 Type을 통해 찾게 됩니다.

즉, @Autowired 대신 @ResourceBean ID를 명시해 주면 @Autowired@QualifierBean ID를 명시해 준 것과 같은 효과를 갖게 됩니다.


  • Spring에서는 @Autowired가 제공되기 때문에 일관성을 위해 @Resource 사용은 지양하는 경우가 많습니다.

반응형

댓글