Spring Framework. Урок 8: Жизненный цикл бина (Bean Lifecycle). Init, Destroy и Factory методы.
ฝัง
- เผยแพร่เมื่อ 8 ก.พ. 2025
- ПОЛНЫЙ КУРС ПО SPRING (Hibernate, REST, Boot, Security): swiftbook.org/...
Мои уроки по Java EE - • Java EE для начинающих
Продвинутая Java - swiftbook.org/...
Репозиторий прошлого урока (Стартовый проект) - github.com/Nei...
Репозиторий урока - github.com/Nei...
Статья про паттерн "Фабричный Метод" (Factory Method) - refactoring.gu...
Реклама и сотрудничество: alishev.neil@gmail.com
ПОЛНЫЙ КУРС ПО SPRING: swiftbook.org/courses/438
Плейлист этого курса: th-cam.com/play/PLAma_mKffTOR5o0WNHnY0mTjKxnCgSXrZ.html
Telegram: t.me/alishev_g
Обнаружил интересный момент: первый prototype-бин, так же как и singleton, создается при старте контекста, даже если далее он ни где не используется. Наиль, подскажите пожалуйста, что с этим бином дальше происходит? Он просто остается в памяти до первого прохода GC (мое предположение, думаю так, в виду того, что сильных ссылок на него ни где нет) или существует все время работы контекста? Если существует, то можно ли от него избавиться как-то?
@@wetergshsghsfghsfh я канеш не Наиль =), но у меня бины ( prototype ) создаются только при созднании ( инициализации ) этого бина. Если не прав, поправте.
Spring почему-то может вызывать заприваченные конструкторы и создавать объекты. Причём без объявленного фабричного метода. С чем это может быть связано?
upd: мы сами не можем вызвать данный конструктор с main, что и ожидается. Я, конечно, не эксперт по безопасности, но это дыра в безопасности, связанная с Spring. Нужно ли латать данную дыру?
через рефлексию можно вызывать и менять даже приватные поля/методы
@@chaosmike2418 совсем забыл про эту "замечательную" возможность.
Не могу не похвалить отлично поставленную речь, качество записи и шикарное произношение на английском. Я в диком восторге.
Спасибо!
Английский так себе. Но это дело наживное. Спасибо за курс !!!
Учусь уже на третьем курсе, на далеко не самой плохой специальности, но получаю больше полезного материала на бесплатном ютубе, чем в универе за немаленькие деньги. Спасибо за вашу деятельность уроки на 42 из 10)
Офигенные уроки, жаль выходят редко ((
Наиль, превращаешь Спринг в приятную игрушку, доступную пониманию для всех и каждого ) Спасибо!
43 тысячи просмотров только одного видоса из всего курса! Это очень круто! Это реально нужно людям, люди смотрят, учатся. Очень круто! Спасибо огромнейшее!
Большое спасибо, Наиль! Твои видео и объяснения, лучшие и наверное единственные из русскоязычных с хорошо поставленной речью! Приятно слушать, смотреть и учиться.
Наиль, продолжай пожалуйста. Очень нужны твои уроки
Огромное спасибо за понятные и простые уроки. Такие видео стоит ждать столько, сколько требуется. Тем более, что автор делится знаниями на абсолютно добровольных началах и ничего никому не должен. Терпеливо мониторим обновления.
Реально лучшие уроки, что я встретил по Спрингу, без воды, все по сути. Еще и небольшие самостоятельные задания есть :)
Лучший!)
Наиль пили есчо! Всё посмотрел) Очень годно! Молодец!
Шикарные уроки, особенно перед собесом повторить))
устроился?
Спасибо тебе за то, что ты делаешь!
Благодарю Вас! Просто великолепно предоставляете материал. Слушать Вас - одно удовольствие! Вы очень большой молодец!!!!!!!!!!!!!!!!!!!!!!!!!
Как всегда на высшем уровне
Огромное спасибо за столь доходчивое и грамотное объяснение!
как успехи?
Огромное тебе спасибо, Наиль, за такие прекрасные уроки)
Лучшие уроки из всех что встречал, продолжайте!
Наконец-то, спасибо за урок!
Как кайфово, что рефакторинг гуру продвигается в массы!
Благодарю, всё очень доходчиво
Ураааааа!!!!)
Новое видео!!!)
Спасибо)))
то чувство когда за час просмотренных лекций узнал столько же сколько на 300 страницах книги про спринг
Смотря какая книга. Но там иногда очень глубоко копают, что одновременно может являться как плюсом, так и минусом.
плохо читал значит)
Очень нужен курс по Hibernate от вас, а то после вашего подхода индусов вообще невозможно воспринимать в качестве лектора. С огромным удовольствием стану спонсором, как только найду способ, так как все карты не подходят.
Паттерн проектирования "Фабричный метод" заключается в делегировании создания объектов с которыми работает класс классам-потомкам. Для этого создается абстрактный метод напр. getInstance() который возвращает нужный объект, а его конкретная реализация определяется в классах-потомках.
+ Даже если сделать конструктор приватным, у спринга все равно получится создать объект даже без фабричного метода, предположу, что из за использования механизма рефлексии доступ к приватному конструктору все равно есть.
Супер! Жду продолжение!
Наиль, отличные уроки! Спасибо!
Спасибо. Продолжайте!
Молодца. Умеет объяснять!
Добрый вечер) Спасибо за ваши курсы) Очень поучительные)
Хотел спросить почему у вас подсказки выходят на хмл. Тоесть если есть метод и вы пишите factory method он подсказывает какой метод нужен 16:50 , но у меня такого нет в idea( Как быть) Заранее спасибо)
без води ... гениально... Огромное спасибо>>>
Спасибо за сайт с Паттернами!!!
Урааа!! Спасибо огромное!!!
Всё понятно и доступно, но хочется более сложного примера)) с реальным применением.
Очень достойные уроки. Наиль, спасибо! Вот что значит есть способности к преподаванию.
Спасибо, отличные уроки
Spasibo!
классные уроки. как человек не разбирающийся ещё в spring ожидал здесь же увидеть порядок destroy от зависимостей(если они вообще есть) и как передавать параметры в фабричный метод(опять же если есть). пойду погуглю.
Спасибо за ваши уроки. Без сомнения это лучшее что я видел. Маленькое замечание по фабричному методу, возможно его стоило поместить в MusicPlayer ведь не очевидно как бы тогда описывался этот метод в контексте.
Момент про то, что singleton с фабричным методом остаётся singleton, был для меня новым. Спасибо
Урааа, видосик
Видео закончилось на самом интересном))
Скоро будет продолжение))
We love you!
Очень здорово, получается, синглтон создаётся сразу в контексте, а прототайп только в случае вызова метода гетБин().
Если же не закрывать контекст, все синглтон бины остануться висеть в памяти, вот одна из причин, почему вааажно закрывать контекст.
Спасибо, супер наглядно получается с методами инит() и дистрой().
кстати, в spring по-умолчанию используется eager-инициализация для скоупа sinlgeton и lazy-инициализация для скоупа prototype... если вам нужно поменять тип инициализации, то при объявлении бина нужно добавить тег lazy-init
замечание: у prototype скоупа всегда будет lazy-инициализаци (что логично)
Наконец то 🤟🏻🤟🏻🤟🏻🤟🏻🤟🏻🤟🏻
8:05 не очень четко объясняется жизненный цикл бина в этом месте. Если бин описан в scope Singleton, то он будет создан и инициирован до вызова метода getBean, если же бин описан в scope Prototype, то создание и инициализация бина будет при вызове метода getBean, что естественно.
16:24 Spring не обращает внимания на приватность конструктора и спокойно умеет создавать объекты через new даже на приватном конструкторе (так же как и приватность методов init и destroy не имеет значения для Spring)
то есть Prototype и есть lazy init..
привет Нил, я вот напоролся на один факт на 8:32 минуте ты обесняеш когда вызывается эти 2 метода только вот я удалил полностю создание обьектов в методе Main и оставил создание обьекта ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); и закрытие его так вот эти методы вызвались ...... как я понимаю не зависит от того создаёш ты бины или нет в Main-e это работает на подобие Статик Блока в Классе
Подскажите пожалуйста, зачем при вызове метода context.getBean мы кроме названия (id) бина вводим ещё второй параметр ClassicalMusic.class. Казалось бы зачем, мы же в XML-ке уже указали ссылку на него в свойстве class="x.x.x.ClassicalMusic". Зачем нужно указываться ещё раз?
Лайк неглядя от СЕООНЛИ
При запуске приложения: 1. Срабатывает весь код, написанный до чтения из контекста. 2. При чтении из контекста начинают создаваться бины, сначала срабатывает конструктор бина, затем инит метод, затем следующий бин и т.д. 3. Когда мы закрываем контекст, срабатывает дестрой метод. 4. Потом весь код после закрытия контекста. 5. Программа завершает работу.
Spring умный, даже не прописывая factory-method в XML - сам догадывается как нужно работать.
Подскажите, что нужно внедрять через @Bean, а что создавать явно через new?
Чем руководствоваться при принятии решения?
Хмм, у меня при scope="prototype" и 3 вызовах context.getBean инициализация выполняется 4 раза, при двух вызовах context.getBean 3 раза, при одном вызове context.getBean 2 раза. А в видео говорится, что число инициализаций соответствует числу вызовов метода. Это я что-то делаю не так, или ошибка в видео?
Посмотрите, может где-то создается еще один объект (например он внедряется в тот объект, который вы получаете с помощью context.getBean()).
@@alishevN Да, спасибо разобрался. У меня в бине musicPayer лежал контейнер со списком ссылок на другие бины, и когда закомментил в нем ссылку на этот бин стала выполняться только одна инициализация. Я думал что бин не инициализируется пока не вызываем context.getBean, но в случае со списком видимо идет инициализация в момент new ClassPathXmlApplicationContext
Этот бы вопрос в топ, а то столько людей не понимало что происходит. (В том числе и я 😄).
Спасибо
При использовании factory method имеется ввиду фабричный паттерн как я понял. Но с другой стороны если метод создания объектов статический то мы не сможем переопределить этот метод и тогда отпадает смысл самого фабричного паттерна. Нам придетсся для каждого класса создавать свой create метод и спрашивается зачем нам тогда фабричный паттерн? Можете объяснить, пожалуйста
Когда следующий планируется?)
круто!
ждём новые видео)
Я попробовал factory-method на двух bean в singleton и prototype scope.
Для проверки вставил в фабричный метод (getClassicalMusic) вывод на экран "println("factory-method used")" перед "return new ClassicalMusic()".
Оказалось, что метод getClassicalMusic() вызывается, как при создании объекта в singleton scope, так и при prototype scope.
Но при prototype scope каждый объект с разным hash code. Получается автор под конец неправильно сказал про factory-method в prototype scope?
Вопрос, а почему у меня Spring-у получилось создать объект, когда я прописал factory-method, но не указал ему, что надо использовать factory-method? Он ищет подходящий метод автоматически?
А, я нашел, почему. Spring настолько крутой, что он может с помощью reflections (не знаю, как правильней будет на русский перевести) делать конструктор доступным.
Почему то сделал конструктор приватным, фактори метод еще не делал, решил проверить, спринг создал объект нормально. Ему видимо все равно на модификатор конструктора)
за год ничего не поменялось)
@@markg2303 Если не ошибаюсь, то фабричный метод нужен не Спрингу, а самому приложению для реализации специальной логики. Для приложения конструктор будет закрыт, как положено, и фабричный метод будет работать.
Так получается нет никакого смысла создавать фабрику на синглтоне? Она ведь как раз и предназначена для создания множества объектов? То есть надо использовать scope прототип? Или нет? Какой смысл в фабрике тогда? Или это способ адаптации фабрики в уже используемом классе под спринг? Объясни плиз поподробней.
Дестрой бинов происходит в результате context.close()?
Немного не понял с factory method, если я не указываю этот параметр в applicationContext и конструктор приватный, у меня полюбому объект класса ClassicalMusic создавался.
Мало-ли кто-нибудь такой же лопух как я. Если у вас в singletone бине запускается только Init метод а destroy не работает, скорее всего вы закоментили или удалили метод context.close() Два часа мучался пока не сообразил.
Что важно, даже если я создам приватный конструктор ClassicalMusic, я не смогу создать объект словом new, но Spring может создать этот объект
Потому что Spring использует Reflection API и джавовские конструкторы он не использует вообще.
Это вообще круто.
@@gmaster100500 Это вряд ли. Конструктор не только присваивает значения, но и может производить другие операции. Если их не использовать, это значит отбросить логику создания объекта заданную разработчиком.
Ураа
Заметил кое-что интересное: если мы получаем prototype бин, то init-method вызывается, если не получаем и не создаем зависимость от него, то init-method не вызывается
Добрый день подскажите пожалуйста, если создать бины других классов метод init и destroy, которые определены только в Classicmusic, все равно выводятся в консоль?
Что то init метод прошёл а вот destroi нет, в конце метода main есть запуск context.close; ? Eclipse среда если что.
мы уже скучаем по @ннот@циям
Если Spring вызывает указанные init/destroy methods, но мы можем их не указывать явно. Значит ли, что у таких методов есть дефолтное значение?
Уже несколько уроков не дает покоя вопрос.
При создании экземпляра класса (например MusicPlayer) мы дважды ссылаемся на сам класс: сначала в xml application context (class="ru.alishev.springcourse.MusicPlayer"), а затем в самом джава-коде, при создании бина (MusicPlayer.class). К чему это дублирование? Почему в джава-коде нужно снова явно указывать класс если мы его уже указали в xml application context? Это очень странно
когда мы вызываем getBean("name") в коде, мы до этапа выполнения, ничего не знаем о applicationContext.xml и какие бины -> каким классам соответствуют. А с объектом нам нужно дальше работать в коде, следовательно его необходимо привести к нужному нам типу, например к общему интерфейсу или предку и использовать далее (в нашем случае просто к нашему классу). А вызов getBean("name", "class") - просто перегруженный метод, чтобы не приводить тип вручную.
Горбунов Евгений
🤦♂️🤦♂️🤦♂️👊🏼 клоун, как это мы ничего не знаем об applicationContext.xml, если мы на ЭТОМ же контексте и вызываем getBean(id)!!!!!🤦♂️🤦♂️🤦♂️🤦♂️
Правильно ли я понимаю, что Спринг - это большой сложный многофункциональный патерн "Абстрактная фабрика" (и не только)?
До ваших курсов немного почитал книгу "Head First. Паттерны проектирования" - и прям ловлю вьетнамские флешбеки.
Получается Spring вызывает init method два раза? При создании объекта и после внедрения зависимости?
Хорошо, что достаточно текста в презентациях. У кого нет слуха, думаю, лучше смогут лучше понять материал
Сделал приватный конструктор и Spring все равно успешно инициализирует бин через Reflection API
Да, о рефлексии у меня есть уроки здесь: www.udemy.com/course/javarussia/?referralCode=A36A8387475CAFDC6776
Спасибо,
Чем init-method принципиально лучше конструктора/инциализатора класса? добавил в класс с музыкой, он вызывается даже раньше init'a (вне зависимости от scope). з.ы. ролики просто шикарные, огромное спасибо за труд автору
Если внедряются зависимости в поля то init-metod будет уже знать о них, а конструктор еще нет.
Наш лектор в университете дал ссылку на твои видео :) Зачем им платят, не понимаю?
Материал подается очень доступно и понятно. Хочу продолжить изучение (купить курс на udemy). Как оплатить курс рублями в РФ (не используя биткоины) ? Спасибо.
Здравствуйте, Алексей!
Курс доступен в РФ вот здесь: swiftbook.org/courses/438
Сделал все, как в уроке, но дестрой-метод не отработал (сообщение не вывелось, будто его и нет). А инит-метод отработал.
В чём может быть дело? Scope поставил "singleton".
надо закрыть контекст и тогда появится
Почему если поставить scope как prototype, то init метод вызывается два раза?
потому что создается 2 объекта (бина), и срабатывает инит метод каждого из них
Потому, что у нас есть ещё bean musicPlayer, который зависит от бина, который вызывает метод init, но у musicPlayer scope = singleton, и зависимость должна внедриться ещё до метода musicPlayer.getBean(), а именно при вызове метода classPathXmlApplicationContext(), соотвественно создаётся объект первый раз при вызове classPathXmlApplicationContext для musicPlayer, а после этого создаётся объект при вызове метода getBean для класса в котором есть наш метод init
Круто! Очень хорошие уроки) В конце можно было проще немного сказать, что factory-method не влияет на scope)
чем отличается создания объекта через init и через factory-method?
Не пойму один момент.
Если программисты такие ленивые, все пытаются упростить, то почему при getBean вместе с указанием ID нашего бина нужно указать класс?
Насколько я понял ID - уникальный идентификатор бина. Почему этой информации недостаточно?
Вы еще делаете этот курс? Его нет на udemy? Или где то еще. Или может можно уже купить весь курс?
Курс в процессе записи
Уроки супер, на практике очень быстро всё воспринимается!! Интересно почему прописуешь бины через xml? И планируешь ли в будущем уроки с аннотациями?
На следующем уроке уже будут аннотации
Does garbage collector delete the object after calling the ''destroy'' method?
Подскажите, почему если сделать конструктор приватным, то getBean() будет также отдавать бины как и обычно? Контекст что для создания бинов не использует конструктор?
Да, Spring сможет создать бины из класса даже если у этого класса приватный конструктор. Дело в том, что Spring Framework не напрямую использует ключевое слово new для создания новых объектов класса, а использует механизм, который называется Рефлексия (Java Reflection API). С помощью рефлексии Spring Framework обходит все ограничения языка, связанные с областью видимости. Об этом я немного говорю в Уроке 10, где показываю, что Spring может внедрять зависимости даже в приватные поля.
Подробные и понятные уроки про Рефлексию есть в моем курсе "Продвинутая Java" - www.udemy.com/javarussia/?couponCode=ADVANCED_JAVARUSSIA
Спасибо за ответ, все понятно.
Немного не понял, но у меня почему-то создается экземпляр класса с приватным конструктором. При том что фабричный метод даже не создавал.
Это благодаря рефлексии.
напиши сюда этот код
Spring Boot Rest будет через два года? :D
вы берете контент с w3schools? Курс будет полностью бесплатный или продолжение будет платным?
я не знаю, что такое w3schools.
я подумаю.
А почему если в бине установлен scope prototype, то init-метод вызывается 1 лишний раз?
init-метод вызывается каждый раз при создании нового объекта.
@@shtormlbt у меня в коде объект создаётся два раза, а init-метод вызывается три раза. Если я не буду создавать ни одного объекта, то инит-метод вызывается один раз
@@parabola47 нашли причину?
@@mksnkv нет, есть только предложение, что в первый раз объект создаётся системой(т.е. самим спрингом) и никуда не предоставляется..
@@parabola47 насколько я понял, prototype не должен создавать бин, пока не вызовется getBean()
Спрингу все равно на приватный конструктор)) Он создает и с ним)
Я так понимаю он использует рефлексию?
Да, я об этом говорю в одном из следующих уроков.
Подробно рефлексия разбирается в моем курсе “Продвинутая Java” - www.udemy.com/course/javarussia/?couponCode=ADVANCED_JAVARUSSIA
А смысл тогда создавать фабричный метод у класса ClassicalMusic а потом в xml файле говорить о нем спрингу ?
Экземпляр бина будет создаваться при приватном конструкторе и без factory method. Рефлексия?
Да
Что-то не очень понятно в чем смысл фабрики в синглтоне, если она все равно создает только один объект. Ну и то, что в прототайпе инициализация и разрушение объекта не использует тоже вызывает вопросы. В чем смысл таких ограничений?
Почему с приватным конструктором единственный способ создать объект это паблик статик фабричный метод? А как же рефлексия?
Я думаю стоило рассказать про destroy-method подробнее, потому что если выскочит исключение, то destroy-method не сработает и как этого избежать