Простое введение в круговые зависимости Spring

Java Spring
Простое введение в круговые зависимости Spring

Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность

Эта статья участвовала в "Проект «Звезда раскопок»”, чтобы выиграть творческий подарочный пакет и бросить вызов творческим поощрительным деньгам.


Романтический побег на бульваре Сансет Никто не знает, кроме ветра

предисловие

Всем привет, я

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

Но чтобы жить, надо еще терпеть, в конце концов, это еще скверно!

Недавно фанат спросилкруговая зависимостьВопрос, если кто-то еще раз спросит вас в будущем, используйте эту статью, чтобы "повесить и избить" его.

концепция

Что такое циклическая зависимость?

Несколько компонентов зависят друг от друга, образуя замкнутый цикл. Например: А зависит от В, В зависит от С, С зависит от А.

image.png

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

Типы циклических зависимостей и возможность их решения следующие:

название Можно ли разрешить циклические зависимости
Циклическая зависимость конструктора нет
Установка круговых зависимостей да
Циклические зависимости в области прототипа нет

сообщение об ошибке

Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘myDao’: Requested bean is currently in creation: Is there an unresolvable circular reference?

перевести

通过构造函数参数 0 表示的依赖关系未得到满足;嵌套的异常是 创建名称为'myDao'的bean时出错。请求的Bean目前正在创建中。是否存在一个无法解决的循环引用?

Информация об исключении: компонент в настоящее время создан ненормальноorg.springframework.beans.factory.BeanCurrentlyInCreationException。

понимание популярной версии

Двое столкнулись друг с другом с оружием

Теперь два человека, A и B, стоят лицом друг к другу с оружием. A говорит, что B выпустит его первым, а B говорит, что A выпустит его первым. Только не стреляй.

Эй, просто играй!

Я думаю, что все видели эту сцену в телевизионных драмах, и в конце обычно «злодей умер от лишнего разговора».

но вернемся к намspringВо-первых, мы не хотим, чтобы кто-то умер, то есть их должно быть двое.beanВсе создано, что делать?

Кто-то должен пойти на компромисс

Решение таково: кто-то должен сначала пойти на компромисс.

А сказал: я делаю шаг назад, я сначала разгрузил магазин, ты положил пистолет.

Б был тронут, когда услышал это, и опустил пистолет, полный слез.

Когда А увидел, что Б не бьет себя, у него на глаза навернулись слезы, и они крепко обнялись.

Живите счастливой жизнью с тех пор...

Понимание весенней версии

вернуться к намspring, Давайте рассмотримbeanЖизненный цикл:

  • создавать экземпляр
  • уступка имущества
  • инициализация
  • разрушать

Простое понимание вышеописанного процесса

实例化и初始化В чем разница?

Отсутствует только процесс промежуточного присваивания, который только инстанцируется?beanМожно ли его использовать?

Конечно, нет!

Иными словами, только экземпляр bean-компонента является полуфабрикатом, а готовый продукт можно использовать после инициализации.

Теперь А зависит от Б, а Б зависит от А.

А сказал Б: Я хочу тебя всего

b также к a: я хочу тебя целиком

Хорошо, двое подрались и столкнулись друг с другом с оружием. Как с этим бороться? Вы должны идти на компромисс в одиночку.

а сказал: Забудь, ты даешь мне свой полуфабрикат, и я его возьму.

b подумал про себя, он использовал мой полуфабрикат для создания полного a, и тогда я мог бы его создать.

Подумав об этом в глубине души, я с готовностью согласился: хорошо, нет проблем.

Таким образом, а создает полное «я», а б содержит а и также завершает творение.

проблема решена.

Это действительно решено? Где существуют готовые продукты и полуфабрикаты?

Это должно упомянуть знаменитый кеш L3.

Кэш L3

Spring предоставляет трехуровневый кеш для хранения готовых изделий и полуфабрикатов и фабрик. родыDefaultSingletonBeanRegistryв классе.

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {   
	/**
	*一级缓存:单例池
	*存放已经初始化的bean——成品
	*/
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    /**
	*三级缓存:单例工厂的高速缓存
	*存放生成bean的工厂
	*/
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
    /**
	*二级缓存:早期单例对象的高速缓存
	*存放已经实例化但未初始化(未填充属性)的的bean——半成品
	*/
    private final Map<String, Object> earlySingletonObjects = new HashMap(16);
}

Процесс создания (облегченная версия)

Если вы рейдер на интервью, рекомендуется скачать упрощенную версию, и вы сможете справиться с интервью.

Посмотрите на исходную версию, когда у вас будет время

Если A зависит от B, а B зависит от A, то между двумя классами образуется циклическая зависимость.

  • A начинает создавать первым, создает экземпляр bean-компонента с помощью своего конструктора без аргументов и помещает свой экземпляр в «кэш второго уровня», чтобы выставить его заранее. Остановка.
  • Б начинает творить, сначала заходим в "кэш 1 уровня", чтобы найти готовый продукт А, но не можем его найти, затем заходим в "кэш 2 уровня", но все еще не можем его найти, затем заходим в «кэш уровня 3», чтобы найти творение А. Фабрика через фабрику получает полуфабрикат А и помещает А в «кэш второго уровня».
  • Получив A, B завершает создание и помещает себя в «кеш первого уровня».
  • В это время A продолжает создавать, а также начинает с «кэша 1-го уровня», после получения B завершает создание и помещает себя в «кэш 1-го уровня».

Процесс создания (исходная версия)

Версию исходного кода рекомендуется использовать вместе с исходным кодом Spring во время отладки.

1. Когда мы вызываем getBean() для получения bean-компонента, фактически вызывается метод doGetBean(). doGetBean() хочет получить beanA, поэтому вызовите метод getSingleton(), чтобы найти beanA из кеша.

2. В методе getSingleton() выполнить поиск из «кэша первого уровня», если нет, вернуть null

3. beanA, полученный в методе doGetBean(), имеет значение null, поэтому выполните соответствующую логику обработки и вызовите перегруженный метод getSingleton() (параметр — ObjectFactory).

4. В методе getSingleton() сначала добавьте beanA_name в коллекцию, чтобы отметить, что компонент создается, а затем вызовите метод createBean анонимного внутреннего класса.

5. Введите AbstractAutowireCapableBeanFactory#doCreateBean, сначала обдумайте и вызовите конструктор для создания экземпляра beanA, а затем оцените, является ли он синглтоном, разрешено ли ему заранее выставлять ссылки (как правило, верно для синглетонов) и является ли он созданный (то есть находится ли он в первом наборе из четырех шагов) оценивается как истинный, затем beanA добавляется в «кэш третьего уровня»

6. Заполните свойства bean A. В это время обнаружено, что bean A зависит от bean B, поэтому он ищет bean B

7. Вызовите метод doGetBean(), такой же, как процесс beanA выше, запросите beanB в кеше, создайте его, если нет, а затем заполните beanB атрибутами.

8. В это время beanB зависит от beanA и вызывает getSingleton() для получения beanA и поочередно находит его в кэшах первого уровня, второго уровня и третьего уровня.В это время фабрика создания beanA получается из «кеша третьего уровня» и получается путем создания фабрики.Для singletonObject этот singletonObject указывает на beanA, созданный в методе doCreateBean() выше

9. Таким образом, beanB получает зависимости beanA, поэтому beanB успешно завершает инициализацию и перемещает beanA из «кеша третьего уровня» в «кэш второго уровня».

10. Далее beanA продолжает свою работу по заполнению атрибутов, а beanB в это время также получается, и beanA также завершает создание, возвращается к методу getSingleton() и продолжает выполнение вниз, перемещая beanA из "кэша второго уровня" в "кэш первого уровня". кеш уровня"

image-20210729201728917

Наконец

Друг разработал для меня новый логотип, какой из них, по вашему мнению, лучше?

image-20210729202951923

Оставьте сообщение в области комментариев, чтобы принять участие в лотерее, официальный представитель Nuggets будет вПроект «Звезда раскопок»После события 100 штук Наггетсов будут разыграны в области комментариев.

Чтобы отблагодарить всех фанатов, мы подготовили для всех высококачественный ресурс, накопленный за эти годы, включая обучающие видео, материалы интервью и бесценные электронные книги.Получать

在这里插入图片描述