Жизненный цикл Spring-бина
Last updated: 10 мая 2025 г.Жизненный цикл спринг бина таков:
- В Java программе создается объект BeanFactory
- В нем создаются бины и внедряются зависимости
- Потом вызывается метод указанный в init-method у бина в конфигурационном xml файле
- Потом созданные бины в BeanFactory извлекаются оттуда и используются
- Вызов context.close() завершает работу BeanFactory и при этом уничтожаются бины, но перед этим вызывается метод указанный в destroy-method.
Что же это за init-method
и destroy-method
?
Это что-то типа init и destroy методов в сервлете. Как мы помним, init
метод нужен в сервлете для инициализации каких-то данных при создании объекта сервлета, а destroy
метод нужен для освобождения каких-то ресурсов перед уничтожением объекта сервлета.
init-method и destroy-method, это то же самое, только с бином.
init и destroy методы определяются в классе бина. Могут иметь любое имя. Давайте же добавим их в класс ServerPC
.
ServerPC:
1package com.someclasses;
2
3public class ServerPC{
4 private Administrator admin;
5 private String pcid;
6 private String pcBrand;
7
8 ServerPC() {}
9 //Чтобы продемонстрировать жизненный цикл
10 //бина добавим вывод строки на консоль
11 //при внедрении в бин другого бина
12 //с помощью конструктора ниже. эта строка
13 //выведется на консоль раньше чем те которые
14 //выводят новые init, destroy методы ниже.
15 ServerPC(Administrator admin) {
16 this.admin = admin;
17 System.out.println("Bean is Created!");
18 }
19
20 //это init метод он вызывается сразу после
21 //создания бина класса ServerPC
22 public void someInicializationsMethod() {
23 System.out.println("Some inicializations");
24 }
25
26 //это destroy метод он вызывается перед
27 //уничтожением BeanFactory и перед уничтожением
28 //бинов.
29 public void someCleaningsMethod() {
30 System.out.println("Some clean up");
31 }
32
33 public void setAdmin(Administrator admin) {
34 this.admin = admin;
35 }
36
37 public Administrator getAdmin() {
38 return admin;
39 }
40
41 public void setPCid(String pcid) {
42 this.pcid = pcid;
43 }
44
45 public void setPCBrand(String pcBrand) {
46 this.pcBrand = pcBrand;
47 //В этом сеттере тоже добавим
48 //вывод строки на консоль. Тоже для
49 //демонстрации жизненного цикла.
50 System.out.println("Bean in use!");
51 }
52
53 public String getPCid() {
54 return pcid;
55 }
56
57 public String getPCBrand() {
58 return pcBrand;
59 }
60
61 public String getAdminMessage(){
62 return admin.adminMessage();
63 }
64}
Давайте сконфигурируем два бина. Один будет с scope singleton
, другой с scope prototype
. И определим у них init и destroy методы.
applicationContext.xml:
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context.xsd">
9
10 <bean id="someAdminBean" class="com.someclasses.Administrator">
11 </bean>
12
13 <!--С помощью атрибутов init-method и
14 destroy-method делаем так чтобы при создании
15 бинов serverPCBeanSingletonScope и
16 serverPCBeanPototypeScope вызывался метод
17 someInicializationsMethod, а при уничтожении
18 этих бинов вызывался метод someCleaningsMethod.-->
19 <bean id="serverPCBeanSingletonScope"
20 class="com.someclasses.ServerPC" scope="singleton"
21 init-method="someInicializationsMethod"
22 destroy-method="someCleaningsMethod">
23 <constructor-arg ref="someAdminBean"/>
24 </bean>
25
26 <bean id="serverPCBeanPototypeScope"
27 class="com.someclasses.ServerPC" scope="prototype"
28 init-method="someInicializationsMethod"
29 destroy-method="someCleaningsMethod">
30 <constructor-arg ref="someAdminBean"/>
31 </bean>
32
33</beans>
Теперь давайте в сервлете создадим, извлечем, используем и уничтожим бины в определенной последовательности для демонстрации жизненного цикла бина.
Пример программы:
1import javax.servlet.*;
2import javax.servlet.http.*;
3import javax.servlet.ServletException;
4import javax.servlet.annotation.WebServlet;
5import java.io.*;
6import org.springframework.context.support.ClassPathXmlApplicationContext;
7import com.someclasses.ServerPC;
8
9@WebServlet("/springservlet")
10public class SpringServlet extends HttpServlet{
11 protected void doGet(HttpServletRequest req,
12 HttpServletResponse resp)
13 throws ServletException, IOException {
14 //при создании BeanFactory создаётся бин со
15 //скоупом singleton и сразу после его создания
16 //у него вызывается метод инициализации, который
17 //был у него указан в атрибуте init-method.
18 ClassPathXmlApplicationContext context =
19 new ClassPathXmlApplicationContext(
20 "applicationContext.xml");
21
22 //После создания бинов в context
23 //пусть выведется любое сообщение в сервлете.
24 System.out.println("Some message");
25
26 //Достаем бин из context
27 ServerPC serverpcSingleton =
28 context.getBean(
29 "serverPCBeanSingletonScope",ServerPC.class);
30 //используем бин
31 serverpcSingleton.setPCid("12353425");
32 System.out.println(serverpcSingleton.getPCid());
33
34 //Бин же со скоупом prototype создаётся
35 //при вызове getBean и соответственно
36 //init метод указанный у него в init-method
37 //вызывается при вызове getBean.
38 ServerPC serverpcPrototype =
39 context.getBean(
40 "serverPCBeanPrototypeScope",ServerPC.class);
41 //используем другой бин
42 serverpcPrototype.setPCid("4567452563");
43 System.out.println(serverpcPrototype.getPCid());
44
45 //Перед удалением объекта BeanFactory
46 //и бинов в нем вызывать destroy
47 //метод someCleaningsMethod
48 context.close();
49 }
50}
Компилируем Java файлики. Файл сервлета при этом компилируем с использованием jar файлов спринг:

Запускаем Tomcat и открываем страницу сервлета по пути /springservlet
и смотрим в консоль Tomcаt сервера:

Как видим, сразу создался бин со скоупом синглтон
. об этом говорит строка Bean is Created!, которую выводит конструктор при создании бина serverPCBeanpSingletonScope
.
Сразу после создания этого бина вызывается init
метод, который выводит строку Some initializations.
Создание бина синглтона же случилось при создании Beanfactory
, а не при вызове getBean
этого бина. Это доказывает третья строка в консоли, которая выведена в консоль между созданием объектаа BeanFactory и вызовом getBean бина синглтона.
Далее мы воспользовались этим бином вывели у него значение поля.
Теперь же создается бин serverPCBeanpPototypeScope
со скоупом prototype
когда вызывается getBean
этого бина. При этом, конструктор выводит сообщение при создании бина и сразу после этого вызывается метод инициализации, который тоже выводит сообщение.
После этого этот бин используется. Выводиться значение его поля.
И в конце программы вызывается context.close()
; который перед удалением бинов и объекта BeanFactory
вызывает destroy метод, который выводит последнюю Some Clean Up.
Выводы о Spring Framework
И в итоге можно еще не до конца понимать зачем нужен этот ваш Spring Framework, все эти бины, если создание и внедрение бинов можно с легкостью выполнять в java классе кодом:
Administrator admin = new Administrator();
ServerPC serverPC = new ServerPC(admin);
Таких DI "матрешек"
в обычном (не спринг) веб-приложении с большим количеством классов будет очень много, а Spring Framework предлагает вынести их в отдельный конфигурационный файл и спринг сам будет создавать объекты сконфигурированных бинов и устанавливать зависимости, а java код самого приложения будет чист нам останется лишь только извлечь созданные объекты из пула объектов созданных спрингом.
Может показаться кода в целом стало больше (код конф файла плюс некоторый код для извлечения бинов в самом приложении), но истенный смысл Spring Framework становится очевидным только разработчикам, которым приходилось вручную управлять всеми этими DI «матрёшками» в крупных не-Spring проектах. Когда мы дойдем до Spring аннотаций о смысле Spring Framework не придется задумываться, там не нужно будет конфигурировать бины в отдельном файле и писать много кода, их конфигурация будет происходить простыми аннотациями в коде классов.
Также, поскольку спринг сам берет на себя ответственность за создание объектов, он может и добавлять к ним некоторую доп функциональность (какую-то мы уже видели – добавление скоупов, методов при иниц. или уничтожении).
Функциональность Spring сегодня уже не ограничивается просто созданием и внедрением бинов. Spring сегодня предоставляет огромное количество различных средств для разработки Веб-приложений, которые будут рассмотрены в этом курсе.
Следующие уроки
Конфигурация Spring бинов с помощью аннотаций
20
мин.
Аннотация @Autowired в Spring Framework
12
мин.
Конфигурация Spring бинов с помощью java класса.
14
мин.