Java for Beginner
672 subscribers
540 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
@Qualifier

В Spring может возникнуть ситуация, когда в контейнере существует несколько бинов одного типа, и Spring не знает, какой из них использовать для внедрения зависимости. Чтобы разрешить эту проблему, используется аннотация
@Qualifier, которая помогает точно указать, какой бин необходимо внедрить, когда существует несколько кандидатов для зависимости.

Аннотация @Qualifier используется вместе с @Autowired для уточнения, какой именно бин должен быть внедрён.

Проблема выбора между несколькими бинами

Рассмотрим пример: у нас есть несколько реализаций одного интерфейса, и нам нужно выбрать конкретную реализацию для внедрения. Без использования @Qualifier Spring не сможет автоматически решить, какой бин использовать, и выбросит исключение NoUniqueBeanDefinitionException.
@Component
public class EmailService implements NotificationService {
@Override
public void sendNotification(String message) {
System.out.println("Отправка email: " + message);
}
}

@Component
public class SmsService implements NotificationService {
@Override
public void sendNotification(String message) {
System.out.println("Отправка SMS: " + message);
}
}

@Component
public class NotificationClient {

@Autowired
private NotificationService notificationService;

public void process() {
notificationService.sendNotification("Привет!");
}
}
В данном примере NotificationClient не сможет корректно работать, так как Spring не знает, какой бин — EmailService или SmsService — использовать для внедрения.


Использование @Qualifier для решения проблемы

Чтобы указать Spring, какой бин использовать, мы добавляем аннотацию @Qualifier, в которой указываем имя конкретного бина.
@Component
public class EmailService implements NotificationService {
@Override
public void sendNotification(String message) {
System.out.println("Отправка email: " + message);
}
}

@Component
public class SmsService implements NotificationService {
@Override
public void sendNotification(String message) {
System.out.println("Отправка SMS: " + message);
}
}

@Component
public class NotificationClient {

private final NotificationService notificationService;

// Указываем, что нужно использовать EmailService
@Autowired
public NotificationClient(@Qualifier("emailService") NotificationService notificationService) {
this.notificationService = notificationService;
}

public void process() {
notificationService.sendNotification("Привет!");
}
}
Здесь с помощью @Qualifier("emailService") мы указываем Spring, что для зависимости NotificationService нужно использовать именно бин emailService.


#Java #Training #Spring #Qualifier
Использование @Qualifier на уровне поля

Аннотацию @Qualifier можно использовать не только на уровне конструктора, но и на уровне полей или методов.

Пример с использованием на поле
@Component
public class NotificationClient {

@Autowired
@Qualifier("smsService") // Указываем бин smsService
private NotificationService notificationService;

public void process() {
notificationService.sendNotification("Привет!");
}
}


Использование @Qualifier с коллекциями

В некоторых случаях может потребоваться внедрить несколько бинов одного типа. Для этого можно использовать коллекции и
@Qualifier для выбора конкретных бинов.

Пример с коллекцией бинов
@Component
public class NotificationProcessor {

private final List<NotificationService> notificationServices;

@Autowired
public NotificationProcessor(@Qualifier("emailService") List<NotificationService> notificationServices) {
this.notificationServices = notificationServices;
}

public void processAll(String message) {
for (NotificationService service : notificationServices) {
service.sendNotification(message);
}
}
}
В этом примере Spring внедрит все бины, реализующие интерфейс NotificationService, в виде списка.


Использование @Qualifier с кастомными именами бинов

Spring автоматически создаёт имя бина, используя имя класса с маленькой буквы. Однако с помощью аннотации @Component можно указать своё имя бина, а затем использовать это имя в @Qualifier.

Пример с кастомным именем бина
@Component("customEmailService")
public class EmailService implements NotificationService {
@Override
public void sendNotification(String message) {
System.out.println("Отправка email: " + message);
}
}

@Component
public class NotificationClient {

@Autowired
@Qualifier("customEmailService") // Указываем кастомное имя бина
private NotificationService notificationService;

public void process() {
notificationService.sendNotification("Привет!");
}
}


#Java #Training #Spring #Qualifier
Что выведет код?

Задача по Spring. Тема: #Autowired и #Qualifier. Сложность средняя.

Подробный разбор через 30 минут!🫡

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class Config2510 {
@Bean
public Service2510 serviceA() {
return new ServiceA2510();
}

@Bean
public Service2510 serviceB() {
return new ServiceB2510();
}

@Bean
public Client2510 client(@Qualifier("serviceA") Service2510 service) {
return new Client2510(service);
}
}

interface Service2510 {
void execute();
}

class ServiceA2510 implements Service2510 {
public void execute() {
System.out.println("Service A executed");
}
}

class ServiceB2510 implements Service2510 {
public void execute() {
System.out.println("Service B executed");
}
}

class Client2510 {
private Service2510 service;

@Autowired
public Client2510(@Qualifier("serviceA") Service2510 service) {
this.service = service;
}

public void run() {
service.execute();
}
}

public class Task251024_2 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config2510.class);
Client2510 client = context.getBean(Client2510.class);
client.run();
context.close();
}
}


#TasksSpring