Циклические зависимости сервисов.md
This commit is contained in:
parent
1bb4d2c53f
commit
7a7f4d17c6
133
dev/architecture/Циклические зависимости сервисов.md
Normal file
133
dev/architecture/Циклические зависимости сервисов.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
---
|
||||||
|
aliases:
|
||||||
|
tags:
|
||||||
|
- maturity/🌱
|
||||||
|
date:
|
||||||
|
- - 2023-11-20
|
||||||
|
zero-link:
|
||||||
|
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
|
||||||
|
parents:
|
||||||
|
linked:
|
||||||
|
---
|
||||||
|
Циклические зависимости между сервисами возникают, когда сервисы взаимно внедряются друг в друга. Например, сервис А внедряет сервис Б, но в тоже время сервис Б внедряет сервис А. В этом случае [SpringBoot](../../meta/zero/00%20SpringBoot.md) и [Quarkus](../../meta/zero/00%20Quarkus.md) не знают, как создать такие бины и внедрить их друг в друга.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Обычно такая ситуация сигнализирует о плохо продуманной архитектуре приложения.
|
||||||
|
|
||||||
|
Пример циклической зависимости в Spring:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceOne {
|
||||||
|
|
||||||
|
private final ServiceTwo serviceTwo;
|
||||||
|
|
||||||
|
public ServiceOne(ServiceTwo serviceTwo) {
|
||||||
|
this.serviceTwo = serviceTwo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceTwo {
|
||||||
|
|
||||||
|
private final ServiceOne serviceOne;
|
||||||
|
|
||||||
|
public ServiceTwo(ServiceOne serviceOne) {
|
||||||
|
this.serviceOne = serviceOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Вот что вы можете с этим сделать:
|
||||||
|
## Пересмотреть архитектуру приложения
|
||||||
|
==Это предпочтительный вариант.== Возможно вам стоит создать сервис В, который внедрит в себя сервисы А и Б. В таком случае вы распутаете циклическую зависимость.
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceThree {
|
||||||
|
|
||||||
|
private final ServiceOne serviceOne;
|
||||||
|
private final ServiceTwo serviceTwo;
|
||||||
|
|
||||||
|
public ServiceThree(ServiceOne serviceOne, ServiceTwo serviceTwo) {
|
||||||
|
this.serviceOne = serviceOne;
|
||||||
|
this.serviceTwo = serviceTwo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceOne {
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceTwo {
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Ленивое внедрение
|
||||||
|
В Spring вы можете указать аннотацию `@Lazy` у аргумента конструктора одного их сервисов. Таким образом сначала будет создан один сервис, для второго сервиса спринг создаст прокси класс, создаст из него бин и внедрит его в ваш сервис. После чего создаст второй сервис и внедрит туда уже созданный первый. А далее заменит ссылку с прокси объекта на второй сервис.
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceTwo {
|
||||||
|
|
||||||
|
private final ServiceOne serviceOne;
|
||||||
|
|
||||||
|
public ServiceTwo(@Lazy ServiceOne serviceOne) {
|
||||||
|
this.serviceOne = serviceOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceOne {
|
||||||
|
|
||||||
|
private final ServiceTwo serviceTwo;
|
||||||
|
|
||||||
|
public ServiceOne(ServiceTwo serviceTwo) {
|
||||||
|
this.serviceTwo = serviceTwo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Внедрение через Setter
|
||||||
|
Внедрить один из сервисов через сеттер, вместо конструктора. Таким образом, фреймворк сможет создать оба бина, а потом уже внедрит один в другой.
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceOne {
|
||||||
|
|
||||||
|
private final ServiceTwo serviceTwo;
|
||||||
|
|
||||||
|
public ServiceOne(ServiceTwo serviceTwo) {
|
||||||
|
this.serviceTwo = serviceTwo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class ServiceTwo {
|
||||||
|
|
||||||
|
private ServiceOne serviceOne;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setServiceOne(ServiceOne serviceOne) {
|
||||||
|
this.serviceOne = serviceOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
@ -18,6 +18,6 @@ linked:
|
|||||||
|
|
||||||
Скорее всего вы увидите состояние файла до выполнения `git reset`.
|
Скорее всего вы увидите состояние файла до выполнения `git reset`.
|
||||||
|
|
||||||
Если же измененных файлов было много, то восстанавливать их по одному довольно муторно. Поэтому нажмите ПКМ по корневой папке проекта и также выберете Local History —> Show History.
|
Если же измененных файлов было много, то восстанавливать их по одному довольно муторно. Поэтому нажмите ПКМ по корневой папке проекта и также выберете `Local History —> Show History`.
|
||||||
|
|
||||||
Вот и все, впредь будьте внимательнее 😊
|
Вот и все, впредь будьте внимательнее 😊
|
3
index.md
3
index.md
@ -35,6 +35,9 @@ enableToc: false
|
|||||||
- [Quarkus](meta/zero/00%20Quarkus.md)
|
- [Quarkus](meta/zero/00%20Quarkus.md)
|
||||||
- [SpringBoot](meta/zero/00%20SpringBoot.md)
|
- [SpringBoot](meta/zero/00%20SpringBoot.md)
|
||||||
- [00 Hibernate](meta/zero/00%20Hibernate.md)
|
- [00 Hibernate](meta/zero/00%20Hibernate.md)
|
||||||
|
- Архитектура
|
||||||
|
- [Архитектура ПО](meta/zero/00%20Архитектура%20ПО.md)
|
||||||
|
- [Архитектура ИС](meta/zero/00%20Архитектура%20ИС.md)
|
||||||
- [DevOps](meta/zero/00%20DevOps.md)
|
- [DevOps](meta/zero/00%20DevOps.md)
|
||||||
- [Docker](meta/zero/00%20Docker.md)
|
- [Docker](meta/zero/00%20Docker.md)
|
||||||
- [Snippets](meta/zero/00%20Snippets.md)
|
- [Snippets](meta/zero/00%20Snippets.md)
|
||||||
|
11
meta/zero/00 Архитектура ИС.md
Normal file
11
meta/zero/00 Архитектура ИС.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
tags:
|
||||||
|
- type/zero-link
|
||||||
|
parents:
|
||||||
|
- "[[00 Разработка]]"
|
||||||
|
title: Архитектура ПО
|
||||||
|
---
|
||||||
|
- [Монолитная архитектура](Монолитная%20архитектура.md)
|
||||||
|
- [Микросервисная архитектура](Микросервисная%20архитектура.md)
|
||||||
|
- [Service Oreinted Architecture](Service%20Oreinted%20Architecture.md)
|
||||||
|
- [Трёхзвенная структура](Трёхзвенная%20структура.md)
|
6
meta/zero/00 Архитектура ПО.md
Normal file
6
meta/zero/00 Архитектура ПО.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
tags:
|
||||||
|
- type/zero-link
|
||||||
|
zero-link:
|
||||||
|
- "[[00 Разработка]]"
|
||||||
|
---
|
@ -3,3 +3,6 @@ tags:
|
|||||||
- type/zero-link
|
- type/zero-link
|
||||||
---
|
---
|
||||||
- [Java разработка](00%20Java%20разработка.md)
|
- [Java разработка](00%20Java%20разработка.md)
|
||||||
|
- Архитектура
|
||||||
|
- [Архитектура ПО](00%20Архитектура%20ПО.md)
|
||||||
|
- [Архитектура ИС](00%20Архитектура%20ИС.md)
|
Loading…
Reference in New Issue
Block a user