Spring의 Bean Injection 방식

jayk·2023년 7월 4일

Spring Injection

목록 보기
2/3
  • Spring framework에서는 bean injection 시 bean name / field name을 매칭하여 bean을 찾고, 만약 없으면 Type으로 매칭하여 Bean을 주입한다.
  • Spring framework에서 @Bean 어노테이션을 사용하여 bean을 생성하게 되면, 어노테이션이 붙은 method의 이름이 bean name으로 생성된다.

위와 같은 특성 때문에, Bean Injection 할 때, 아래와 같은 현상이 발생된다.

@Configuration
public class InjectionConfig {
    @Bean
    public ObjectMapper aaaObjectMapper() {
        return new ObjectMapper();
    }

    @Bean
    public ObjectMapper bbbObjectMapper() {
        return new ObjectMapper();
    }
}
public class InjectionTest {
    @Autowired
    private ObjectMapper aaaObjectMapper;

    @Autowired
    private ObjectMapper bbbObjectMapper;

    @Test
    void test() {
        System.out.println(">>> " + aaaObjectMapper);
        System.out.println(">>> " + bbbObjectMapper);
    }
}

테스트 결과를 보면 다른 bean이 주입된 것을 알 수 있다.

>>> com.fasterxml.jackson.databind.ObjectMapper@280a258d
>>> com.fasterxml.jackson.databind.ObjectMapper@bae32f

여기서 configuration은 그대로 두고, autowired를 하나 더 넣으면 어떻게 될까?

public class InjectionTest {
    @Autowired
    private ObjectMapper aaaObjectMapper;

    @Autowired
    private ObjectMapper bbbObjectMapper;
    
    @Autowired
    private ObjectMapper cccObjectMapper;

    @Test
    void test() {
        System.out.println(">>> " + aaaObjectMapper);
        System.out.println(">>> " + bbbObjectMapper);
        System.out.println(">>> " + cccObjectMapper);
    }
}

아래와 같이 에러가 발생된다.

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' available: expected single matching bean but found 2: aaaObjectMapper,bbbObjectMapper

아래와 같은 이유로 에러가 발생되었다.

  • bean injection을 위해 cccObjectMapper라는 Bean name을 찾았지만, 없음
  • Bean type (ObjectMapper)로 찾아봤더니 2개나 있음 (aaaObjectMapper / bbbObjectMapper)
  • 둘 중 어떤걸로 injection을 해야할지 모르겠음

때문에 만약에 bbbObjectMapper Bean 선언 부분을 제거하면 에러가 발생되지 않고, 셋 모두 같은 aaaObjectMapper를 사용하는 것을 확인할 수 있다.
(bean name으로 찾았을 때 없으면 bean type으로 찾기 때문)

@Configuration
public class InjectionConfig {
    @Bean
    public ObjectMapper aaaObjectMapper() {
        return new ObjectMapper();
    }
}
public class InjectionTest {
    @Autowired
    private ObjectMapper aaaObjectMapper;

    @Autowired
    private ObjectMapper bbbObjectMapper;
    
    @Autowired
    private ObjectMapper cccObjectMapper;

    @Test
    void test() {
        System.out.println(">>> " + aaaObjectMapper);
        System.out.println(">>> " + bbbObjectMapper);
        System.out.println(">>> " + cccObjectMapper);
    }
}
>>> com.fasterxml.jackson.databind.ObjectMapper@280a258d
>>> com.fasterxml.jackson.databind.ObjectMapper@280a258d
>>> com.fasterxml.jackson.databind.ObjectMapper@280a258d

*참고(https://tech.kakaopay.com/post/martin-dev-honey-tip-2/)

0개의 댓글