개발/Spring

[Spring] Bean 등록하기 (@Bean vs @Component) / 같은 타입의 Bean 구분하기 (@Primary vs @Qualifier())

서해쭈꾸미 2025. 2. 5. 12:32
Bean 등록하기

 

1. 클래스를 Bean으로 등록하기

@Component 사용

@Component
public class MyService {

    public void serve() {
        System.out.println("Service is serving...");
    }
}

 

@Component를 사용하면 Spring의 @ComponentScan에 의해 자동으로 스캔되고, 클래스를 인스턴스화하여 Spring IoC 컨테이너에 등록된다. 이후 다른 곳에서 의존성 주입을 통해 해당 인스턴스를 사용할 수 있다.

(예시 : @Service, @Repository 등)

 

 

2. 메소드를 Bean으로 등록하기

@Bean 사용

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyService();
    }
}

 

@Bean은 @Configuration 클래스 내의 메소드 수준에서 사용된다. 객체를 직접 생성하고 Spring IoC 컨테이너에 등록할 수 있다.

 

 

결론
어떤 것을 사용하는 게 좋을까 ?

직접 작성한 Class를 Bean에 등록시키고 싶다면 ? -> @Component
외부 라이브러리에 작성되어있는 Class를 Bean에 등록시키고 싶다면 ? -> @Bean

 

 

 

 

 

 

 

같은 타입의 Bean 구분하기 

 

1. 이름으로 구분하기

같은 타입의 Bean은 기본적으로 Bean의 이름으로 구분할 수 있다.

아래와 같이 Food 타입의 Pizza와 Chicken을 Bean으로 등록해두었다고 가정하자.

public interface Food {
	void eat();
}

 

@Component
public class Pizza implements Food {

	@Override
    public void eat() {
    	System.out.println("eat pizza");
    }
}

 

@Component
public class Chicken implements Food {

	@Override
    public void eat() {
    	System.out.println("eat Chicken");
    }
}

 

이후 @Autowired 등으로 Bean을 주입할 때, Food 타입으로 여러개의 Bean이 등록되어있기때문에 타입만으로는 Bean을 찾을 수 없어 오류가 난다.

public Class Test{
    @Autowired
    Food food; //오류 발생. chicken과 pizza 중 어떤 걸 주입해야하는지 알 수 없음.
}

 

따라서 아래와 같이 등록된 이름을 명시해주어 해당 Bean을 주입 받아 사용할 수 있다.

public Class Test{
    @Autowired
    Food pizza;
    
    @Autowired
    Food chicken;
}

 

 

 

2. Primary로 구분하기

같은 타입의 Bean이 여러개 일 때 @Primary 어노테이션을 사용해 주입 될 Bean을 설정해줄 수 있다.

@Component
@Primary
public class Chicken implements Food {

	@Override
    public void eat() {
    	System.out.println("eat Chicken");
    }
}

 

public Class Test{
    @Autowired
    Food food; //primary 설정되어있는 chicken이 주입된다.
}

 

 

 

3. Qualifier로 구분하기

같은 타입의 Bean이 여러개 일 때 @Qualifier 어노테이션을 사용해 주입 될 Bean을 설정해줄 수 있다.

@Component
@Qualifier("pizza")
public class Pizza implements Food {

	@Override
    public void eat() {
    	System.out.println("eat pizza");
    }
}
@Component
@Primary
public class Chicken implements Food {

	@Override
    public void eat() {
    	System.out.println("eat Chicken");
    }
}

 

public Class Test{
    @Autowired
    @Qualifier("pizza")
    Food food; //Qualifier 설정되어있는 pizza가 주입된다.
}

 

위와 같이 Qualifier와 Parimary가 같이 사용되는 경우, 우선순위는 Qualifier > Primary 순이다.

 

 

결론
어떤 것을 사용하는 게 좋을까 ?

범용적으로 사용되는 Bean 객체라면 ? -> @Parimary 사용
지역적으로 사용되는 Bean 객체라면 ? -> @Qualifier 사용