[Spring] Spring Bean 등록 (2)

이연우·2025년 7월 25일

TIL

목록 보기
48/100

🌿 @Qualifier, @Primary

  • 같은 타입의 Bean이 중복된 경우 해결하기 위해 사용하는 Annotation

🎯 Bean 충돌 해결 방법

  • 같은 타입의 Bean이 여러 개 있을 때,
    어떤 Bean을 주입해야 할지 Spring에게 명확히 알려 주는 방법

1️⃣ @Autowired + 필드명 사용

public interface MyService { ... }

@Component
public class MyServiceImplV1 implements MyService { ... }

@Component
public class MyServiceImplV2 implements MyService { ... }

@Component
public class ConflictApp {

	// 필드명을 Bean 이름으로 설정
	@Autowired
	private MyService myServiceImplV2;
	...
}

→ Spring은 타입이 같을 경우 → 필드명 or 파라미터명을 기준으로 주입

2️⃣ @Qualifier 사용 – 별명 붙이기

@Component
@Qualifier("firstService")
public class MyServiceImplV1 implements MyService { ... }

@Component
@Qualifier("secondService")
public class MyServiceImplV2 implements MyService { ... }

@Component
public class ConflictApp {

		private MyService myService;

		// 생성자 주입에 구분자 추가
		@Autowired
		public ConflictApp(@Qualifier("firstService") MyService myService) {
				this.myService = myService;
		}
	
		// setter 주입에 구분자 추가
		@Autowired
		public void setMyService(@Qualifier("firstService") MyService myService) {
				this.myService = myService;
		}
	...
}

→ Bean 등록 시 추가 구분자를 붙여 줌
→ 특정 Bean에 이름표를 붙이고 그 이름으로 주입
생성자 주입, setter 주입 사용 가능

🧠 용도:

  • 동일한 타입의 Bean이 여러 개 있을 때
  • 명시적으로 구분해 주입해야 할 때

3️⃣ @Primary 사용 – 기본 우선순위 지정

  • 여러 Bean 중에서 기본값으로 사용할 Bean 지정
@Component
public class MyServiceImplV1 implements MyService { ... }

@Component
@Primary
public class MyServiceImplV2 implements MyService { ... }

@Component
public class ConflictApp {

		private MyService myService;

		@Autowired
		public ConflictApp(MyService myService) {
				this.myService = myService;
		}
	...
}

@Primary는 하나만 지정 가능
Qualifier가 붙은 경우가 우선

💬 실제 사례

상황사용 방법
MySQL과 Oracle DB 동시 사용MySQL → @Primary / Oracle → @Qualifier("oracle")
여러 구현체 중 하나 기본 지정기본 → @Primary, 나머지 → @Qualifier

🧺 여러 Bean을 한꺼번에 주입하는 방법

@Autowired
private List<MyService> services;

@Autowired
private Map<String, MyService> serviceMap;

→ 모든 Bean을 리스트 또는 맵으로 주입받을 수 있음
→ Bean 이름 → Map의 키로 사용됨


🚀 수동 VS 자동

✅ 자동 등록 (@Component 기반)

방법설명
@Component, @Service, @Repository, @Controller클래스에 어노테이션을 붙이면 자동으로 Bean 등록
@ComponentScan설정 클래스에서 자동 탐색 범위 지정
Spring Boot@SpringBootApplication은 내부적으로 @ComponentScan 포함

🤖 장점

  • 선언만으로 등록 가능
  • OCP, DIP 준수
  • 유지 보수 편리
  • 스프링 부트에서 기본 사용 방식

⚙️ 수동 등록 (@Configuration + @Bean)

상황예시
외부 라이브러리 객체new로 만든 객체를 Bean으로 등록
기술적 설정 (DataSource, TransactionManager 등)환경 설정 파일에 명시적으로 등록
Bean 충돌 우려 시명시적으로 선택해서 등록

⚠️ Bean 충돌 시 우선순위

상황우선순위
수동 vs 자동수동이 우선
@Primary vs @Qualifier@Qualifier가 우선
중복 이름 등록오류 발생 (ConflictingBeanDefinitionException)

🔧 Spring Boot에서는 기본적으로 충돌 시 오류 발생
→ 설정으로 허용 가능:

spring.main.allow-bean-definition-overriding=true

0개의 댓글