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

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

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

Аннотация @Autowired — это ключевой элемент механизма внедрения зависимостей (Dependency Injection, DI) в Spring Framework. Она позволяет Spring автоматически разрешать и внедрять зависимости между компонентами приложения. Вместо того чтобы вручную создавать экземпляры объектов, Spring сам берёт на себя задачу управления зависимостями.

С помощью @Autowired мы можем внедрять зависимости в конструкторы, методы и поля классов, избегая необходимости вручную управлять созданием объектов и передачей зависимостей. Spring Framework автоматически ищет подходящие бины в своём контейнере и внедряет их в нужные классы.

Типы внедрения с использованием @Autowired

Внедрение через конструктор
Внедрение через поле

Внедрение через сеттеры (методы)

1. Внедрение зависимостей через конструктор
Этот подход является предпочтительным в Spring, поскольку он делает классы неизменяемыми и обеспечивает их корректную инициализацию с обязательными зависимостями. Это также облегчает тестирование, так как зависимости передаются через конструктор.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class NotificationService {

private final MessageService messageService;

// Внедрение зависимости через конструктор
@Autowired
public NotificationService(MessageService messageService) {
this.messageService = messageService;
}

public void sendNotification(String message) {
messageService.sendMessage(message);
}
}

@Component
public class MessageService {

public void sendMessage(String message) {
System.out.println("Отправка сообщения: " + message);
}
}
В этом примере NotificationService использует внедрение зависимости MessageService через конструктор. Аннотация @Autowired сообщает Spring, что необходимо внедрить экземпляр MessageService в конструктор.


2. Внедрение зависимостей через поле
При внедрении через поле, @Autowired аннотирует само поле класса, и Spring автоматически внедряет зависимость напрямую в это поле. Хотя это способ более прост и не требует создания явного конструктора, он может затруднить тестирование, так как для тестов необходимо использовать рефлексию или фреймворки типа Mockito для подмены полей.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class NotificationService {

@Autowired
private MessageService messageService;

public void sendNotification(String message) {
messageService.sendMessage(message);
}
}

@Component
public class MessageService {

public void sendMessage(String message) {
System.out.println("Отправка сообщения: " + message);
}
}
Здесь зависимость MessageService внедряется напрямую в поле класса NotificationService.


3. Внедрение зависимостей через сеттеры
Внедрение зависимостей через методы-сеттеры предоставляет возможность изменять зависимости после создания объекта. Это полезно, если зависимость может быть изменяема или опциональна.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class NotificationService {

private MessageService messageService;

// Внедрение зависимости через сеттер
@Autowired
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}

public void sendNotification(String message) {
messageService.sendMessage(message);
}
}

@Component
public class MessageService {

public void sendMessage(String message) {
System.out.println("Отправка сообщения: " + message);
}
}
В данном примере Spring внедряет зависимость через метод-сеттер. Этот подход может быть полезен, если зависимость опциональна или должна изменяться во время работы приложения.


#Java #Training #Spring #Autowired
👍5
Дополнительные возможности @Autowired

Обязательные и необязательные зависимости

По умолчанию аннотация @Autowired требует, чтобы зависимость была доступна в контейнере Spring. Если подходящий бин не найден, Spring выбрасывает исключение NoSuchBeanDefinitionException. Однако можно сделать зависимость необязательной, используя параметр required=false.

Пример необязательной зависимости
@Component
public class NotificationService {

private MessageService messageService;

// Необязательная зависимость
@Autowired(required = false)
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}

public void sendNotification(String message) {
if (messageService != null) {
messageService.sendMessage(message);
} else {
System.out.println("MessageService не доступен.");
}
}
}
В этом примере, если бин MessageService не доступен, метод sendNotification() корректно обработает отсутствие зависимости.


Циклические зависимости

Циклическая зависимость возникает, когда два или более бина зависят друг от друга, что может привести к проблемам при создании этих объектов. Spring может автоматически разрешать некоторые циклические зависимости при использовании внедрения через сеттеры, но это не рекомендуется, так как нарушает принцип инверсии управления.

Преимущества использования @Autowired

Автоматизация: Spring сам управляет созданием и внедрением зависимостей, что упрощает разработку.
Гибкость: Возможность использовать внедрение через конструкторы, сеттеры или поля, в зависимости от архитектурных предпочтений.
Тестируемость: Внедрение через конструкторы и сеттеры делает классы легче тестируемыми.


#Java #Training #Spring #Autowired
👍3
Что выведет код?

Задача по 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
👍2