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
Spring. Внедрение зависимостей через сеттеры

Что такое внедрение зависимостей через сеттеры?

Внедрение через сеттеры — это подход, при котором зависимости передаются в объект с помощью методов-сеттеров. В отличие от внедрения через конструктор, в этом случае зависимости могут быть переданы (или изменены) после создания объекта. Это обеспечивает большую гибкость, особенно если зависимость не обязательна для создания объекта, но может быть добавлена позже.

Spring поддерживает автоматическое внедрение зависимостей через сеттеры с использованием аннотации @Autowired на уровне метода-сеттера или с помощью XML-конфигурации.

Пример внедрения через сеттеры

Давайте рассмотрим пример, где тот же класс NotificationService использует внедрение зависимости через сеттер:
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);
}
}
Здесь MessageService внедряется через метод-сеттер setMessageService() с использованием аннотации @Autowired. В отличие от внедрения через конструктор, здесь зависимость может быть изменена в любое время после создания объекта.



Конфигурация через XML


Если вам необходимо использовать XML-конфигурацию для внедрения зависимости через сеттеры, это можно сделать так:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- Определение бина MessageService -->
<bean id="messageService" class="com.example.MessageService"/>

<!-- Определение бина NotificationService с внедрением через сеттер -->
<bean id="notificationService" class="com.example.NotificationService">
<property name="messageService" ref="messageService"/>
</bean>
</beans>
В этом случае Spring вызовет сеттер setMessageService() и передаст бин messageService в качестве зависимости.


#Java #Training #Spring #Dependency_Injection_via_setters
Преимущества и недостатки внедрения через сеттеры

Преимущества:
Гибкость: Внедрение через сеттеры предоставляет большую гибкость, так как зависимости можно изменить или передать после создания объекта.
Удобство для опциональных зависимостей: Если зависимость не обязательна для работы класса и может быть добавлена позже, использование сеттеров становится более подходящим вариантом.
Возможность поздней инициализации: Вы можете инициализировать или менять зависимости в процессе работы приложения.


Недостатки:
Возможность "полуинициализированного" объекта: Так как зависимости могут быть переданы после создания объекта, существует риск того, что объект может быть использован до того, как все зависимости будут установлены.
Явная зависимость менее очевидна: В отличие от внедрения через конструктор, где зависимости видны при создании объекта, здесь необходимо знать, что сеттеры должны быть вызваны после создания объекта, что может быть не так очевидно.


Когда использовать внедрение через сеттеры?

Опциональные зависимости: Если класс может работать без некоторой зависимости, но она может быть добавлена позже, сеттеры — это хороший вариант.
Переиспользование объекта: В случаях, когда объект должен быть многократно использован с разными зависимостями, сеттеры предоставляют гибкость для изменения этих зависимостей.
Когда зависимость может изменяться во время жизни объекта: Если требуется, чтобы зависимость могла изменяться в процессе работы приложения, сеттеры позволяют это сделать.


Сравнение внедрения через конструктор и через сеттеры

Необходимые зависимости: Внедрение через конструктор лучше подходит для обязательных зависимостей, так как они передаются в момент создания объекта и не могут быть изменены. Сеттеры же подходят для опциональных зависимостей.
Иммутабельность: Конструкторы способствуют созданию неизменяемых объектов, в то время как сеттеры допускают изменение состояния объекта после создания.
Тестируемость: Оба подхода легко тестируются с помощью фреймворков типа Mockito, однако конструкторы делают зависимости более очевидными и уменьшают количество методов для подмены в тестах.



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

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

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

import org.springframework.context.annotation.*;

@Configuration
class Config2410 {
@Bean
public MyService2410 myService2410() {
return new MyService2410();
}

@Bean
public MyBean2410 setterInjectedBean2410(MyService2410 myService) {
MyBean2410 bean = new MyBean2410();
bean.setMyService2410(myService);
return bean;
}

@Bean
public MyBean2410 constructorInjectedBean2410(MyService2410 myService) {
return new MyBean2410(myService);
}
}

class MyService2410 {
public void serve() {
System.out.println("Service called");
}
}

class MyBean2410 {
private MyService2410 myService;

public MyBean2410(MyService2410 myService) {
this.myService = myService;
System.out.println("Constructor injection");
}

public MyBean2410() {
System.out.println("No-arg constructor");
}

public void setMyService2410(MyService2410 myService) {
this.myService = myService;
System.out.println("Setter injection");
}

public void useService2410() {
myService.serve();
}
}

public class Task241024_2 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config2410.class);

MyBean2410 setterBean = context.getBean("setterInjectedBean2410", MyBean2410.class);
MyBean2410 constructorBean = context.getBean("constructorInjectedBean2410", MyBean2410.class);

setterBean.useService2410();
constructorBean.useService2410();

context.close();
}
}


#TasksSpring