15 de agosto de 2026 • Java

06 - Anotações @Primary e @Qualifier para Spring Bean

Por padrão, o Spring injeta dependências por tipo. Quando existe apenas um Bean de um determinado tipo, o Spring sabe exatamente qual Bean deve ser injetado.

Qual é o problema?

@Service
public class EmailNotificationService implements NotificationService {

}

@Service
public class UserService {
  private final NotificationService notificationService;

  public UserService(NotificationService notificationService) {
    this.notificationService = notificationService;
  }
}

# Since there is only one implementation of NotificationService, Spring injects automatically.
# The problem happens when there are multiple Beans of the same type.

@Service
public class EmailNotificationService implements NotificationService {
}

@Service
public class SmsNotificationService implements NotificationService {
}
# Now Spring doesn't know which implementation to inject.
@Service
public class UserService {

    private final NotificationService notificationService;

    public UserService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }
}

A inicialização da aplicação falha com um erro semelhante a:

No qualifying bean of type 'NotificationService' available:
expected single matching bean but found 2

Solução usando anotações?

O Spring oferece duas anotações para resolver essa ambiguidade:

  • @Primary
  • @Qualifier

Ambas indicam ao Spring qual Bean deve ser injetado, mas elas resolvem o problema de maneiras diferentes.

Uso de @Primary e @Qualifier?

@Primary

marca um Bean como a escolha padrão sempre que múltiplos Beans do mesmo tipo existirem.

@Service
@Primary
public class EmailNotificationService implements NotificationService {
}

@Service
public class SmsNotificationService implements NotificationService {
}

Agora esta injeção funciona, o Spring injeta automaticamente EmailNotificationService

@Service
public class UserService {

    private final NotificationService notificationService;

    public UserService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }
}

@Qualifier

Permite que você escolha explicitamente qual Bean injetar.

@Service("emailService")
public class EmailNotificationService implements NotificationService {
}

@Service("smsService")
public class SmsNotificationService implements NotificationService {
}

# Spring injects SmsNotificationService, even if another Bean
is marked as @Primary

@Service
public class UserService {

    private final NotificationService notificationService;

    public UserService(
        @Qualifier("smsService")
        NotificationService notificationService) {

        this.notificationService = notificationService;
    }
}

@Primary vs @Qualifier?

Quando usar @Primary e quando usar @Qualifier?

Use @Primary quando:

  • Uma implementação é usada na maioria das vezes
  • Você deseja um Bean padrão para a aplicação
  • A maioria dos pontos de injeção deve receber a mesma implementação
NotificationService
    ├── EmailNotificationService (@Primary)
    └── SmsNotificationService

Use @Qualifier quando:

  • Serviços diferentes exigem implementações diferentes
  • Você precisa de controle explícito sobre qual Bean é injetado
  • Múltiplas implementações são igualmente importantes e não há um padrão óbvio
@Service
public class MarketingService {

    public MarketingService(
        @Qualifier("emailService")
        NotificationService notificationService) {
    }
}

@Service
public class EmergencyService {

    public EmergencyService(
        @Qualifier("smsService")
        NotificationService notificationService) {
    }
}

Ordem de Prioridade

Quando o Spring resolve dependências, ele segue esta ordem:

  1. @Qualifier (prioridade mais alta)
  2. @Primary
  3. Nome do Bean (em alguns cenários de resolução)
  4. Se a ambiguidade ainda existir, o Spring lança uma exceção
# Although EmailNotificationService is marked with @Primary, Spring injects SmsNotificationService because @Qualifier always takes precedence.

@Service
@Primary
public class EmailNotificationService implements NotificationService {
}

@Service("smsService")
public class SmsNotificationService implements NotificationService {
}

public UserService(
    @Qualifier("smsService")
    NotificationService notificationService) {
}
← Voltar para o blog