Spring - 중복된 빈 등록에 대한 처리


스프링 의존 객체 선택

  • 컴포넌트 Annotation은 싱글톤 범위로 등록되며 같은 타입의 빈이 다른 클래스에서 등록된 경우 에러가 발생한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface Repository {
}
@Repository
public class Repository2 implements Repository{
}
@Repository
public class Repository3 implements Repository{
}
@Service
public class Service{
@Autowired //등록된 빈이 중복되어 에러 발생
Repository repository;
}

해결방법 1. @Primary Annotation을 추가하여 우선순위를 지정

  • 우선순위로 클래스를 등록하도록 선택한다.
  • @Primary 어노테이션 또한 두번 이상 사용될 경우 에러가 발생하므로 주의하여야 한다.
    1
    2
    3
    @Repository @Primary //객체 선택에 우선순위를 지정
    public class Repository2 implements Repository{
    }

해결방법 2. @Qualifier Annotation을 설정하여 조건 설정

  • 해당 bean이 사용할 의존 객체를 선택할 수 있게 한다.
  • Configuration 파일에서 qualifier태그를 통해 빈의 한정자 값을 설정하고 @Qualifier 어노테이션으로 선택할 한정자를
  • 등록하는 빈들의 의존성을 직접 관리할 수 있는 경우에 한하여 사용하는 것이 적절하다. (한정자 값을 갖는 빈 객체가 존재하지 않으면 에러가 발생하기 때문)
1
2
3
<bean id="repository" calss="com.example.Repository">
<qualifier value="id"/>
</bean>
1
2
3
4
public class Component{
@Autowired @Qualifier("id")//id라는 한정자를 갖는 객체를 컨테이너로부터 주입받는다.
private Repository repository;
}

해결방법 3. 해당 타입의 Bean을 하나의 배열에 모두 주입받기

  • List array로 객체를 선언하여 빈에 해당하는 객체를 모두 주입받을 수 있다.
  • 하나의 배열에 동일한 관리를 요할 때 사용할 수 있음.
1
2
3
4
5
@Service
public class Service{
@Autowired //등록된 다수의 Repository 객체를 모두 배열에 주입
List<Repository> repositories;
}

해결 방법 4. Autowired로 주입받는 객체의 이름을 인터페이스가 아닌 클래스의 id로 설정하기

  • Bean이 다수의 클래스에 의해 등록되어도 @Autowired 어노테이션이 붙은 객체의 이름이 특정 클래스의 이름과 동일하다면 해당 클래스의 객체로 주입된다.
  • 이러한 방법의 경우 재활용성이 떨어지기 때문에 좋은 방법으로 사용되지는 않는다.
1
2
3
4
5
@Service
public class Service{
@Autowired //Repository 타입의 Bean이 중복되었지만 클래스 이름이 같은 Repository3 객체가 주입된다.
Repository repository3;
}

댓글