본문 바로가기

프레임워크/Spring boot Annotation

@Qualifier, @Primary

@Autowired, @Resource, @Inject 어노테이션으로만 자동적으로 객체를 주입할 경우 컨테이너에서 주입할 대상이 여러개여서 의존성을 주입하지 못하는 경우가 발생할 수 있다.

 

public class Player {

    @Autowired
    private Weapon weapon;

    Player(){
    }

    public Player(Weapon weapon) {
        super();
        this.weapon = weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }

    public Weapon getWeapon() {
        return weapon;
    }

    public void usePlayerWeapon() {
        weapon.useWeapon();
    }

    public void setPlayerWeaponNow(Weapon weapon) {

    }
}

    // 결과
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gunPlayer': Injection of autowired dependencies failed; nested exception is ...
        ... (생략 ) ...

다음의 코드를 보자.

@Autowired로 Weapon class를 주입받고 있다. 하지만 Bean Conatainer에 Weapon type을 가진 객체가 2개가 등록되어 있다면 어떨까? 바로 위와 같은 Exception이 발생한다.

@Qualifier

@Qualifier("gunner")
public class Player {

    @Autowired
    @Qualifier("gunner")   // appContext.xml 에 명시했던 qulifier name을 쓴다
    private Weapon weapon;

    Player(){
    }

    public Player(Weapon weapon) {
        super();
        this.weapon = weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }

    public Weapon getWeapon() {
        return weapon;
    }

    public void usePlayerWeapon() {
        weapon.useWeapon();
    }

    public void setPlayerWeaponNow(Weapon weapon) {

    }
}

public class Main {

    public static void main(String[] args) {
        String xmlConfigPath = "classpath:appContext.xml";

        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(xmlConfigPath);

        Player gunPlayer = ctx.getBean("gunPlayer", Player.class);
        gunPlayer.usePlayerWeapon();

    }
}

위처럼 겹치는 bean이 여러개 존재할시 @Qualifier 어노테이션을 활용하여 특정 객체로 한정지을수가 있다.

@Primary

@Primary로 같은 우선순위로 있는 클래스가 여러개가 있을 시 그 중 가장 우선순위로 주입할 클래스 타입을 선택할 수 있다.
@Repository @Primary
public class BSRepository implements BookRepository {
}