Tabla de contenido
- 1. El sistema de contenedores de Spring IoC
- En segundo lugar, el momento clave del ciclo de vida del frijol
-
- 1. Analice si la creación de Bean es en el momento de la inicialización del contenedor o en el momento de getBean
- 2. Analiza la llamada al constructor
- 3. Analizar la invocación del método de inicialización afterPropertiesSet de InitializingBean
- 4. Analizar la inicialización e invocación de BeanFactoryPostProcessor
- 5. Analizar la inicialización e invocación de BeanPostProcessor
- 6. Resumen
- Tres, proceso principal de inicialización del contenedor Spring IoC
1. El sistema de contenedores de Spring IoC
El contenedor de IoC es el módulo principal de Spring y una solución de marco que abstrae la gestión de objetos y la gestión de dependencias . Spring proporciona un contenedor, que BeanFactory
es el contenedor superior (contenedor raíz) , no se puede instanciar, lo que define un conjunto de principios que debe cumplir con todos los contenedores de IoC, particularmente un contenedor puede implementar características adicionales, como solíamos hacer ApplicationContext
, más específicamente, bajo tal implementación se ClassPathXmlApplicationContext
incluye un conjunto de análisis de contenido xml y similares, AnnotationConfigApplicationContext
comprendiendo el contenido una serie de análisis de notas o similares. El sistema de herencia de contenedores Spring IoC es muy inteligente. Puede usar el nivel que necesita usar, en lugar de usar funciones grandes y completas.
BeanFactory
El método de interfaz de nivel superior se apila de la siguiente manera: el conector del
BeanFactory
sistema de herencia de vasos a
través de su diseño, podemos ver que siempre hemos usado, ApplicationContext
además de heredar la BeanFactory
sub-interfaz, también heredada ResourceLoader
, MessageSource
y otras interfaces, por lo que su función también proporciona más riqueza.
Aquí tenemos ClasspathXmlApplicationContext
, por ejemplo, una explicación detallada del proceso de inicialización del contenedor IoC de origen.
Este artículo hace referencia a "Spring Advanced Source Notes", estudiantes que necesitan agregar asistente VX: C18173184271 acceso gratuito
En segundo lugar, el momento clave del ciclo de vida del frijol
Idea: Cree una clase LagouBean, deje que implemente varias interfaces especiales y observe la pila de llamadas de subprocesos en el constructor y los puntos de interrupción del método de interfaz de la implementación de la interfaz, y analice el tiempo de activación de los puntos clave de la creación y administración de objetos Bean.
LagouBean
clase
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 11:46
*/
public class LagouBean implements InitializingBean{
/**
* 构造函数
*/
public LagouBean(){
System.out.println("LagouBean 构造器...");
}
/**
* InitializingBean 接⼝实现
*/
public void afterPropertiesSet() throws Exception {
System.out.println("LagouBean afterPropertiesSet...");
}
}
BeanPostProcessor
Clase de implementación de interfaz
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 16:59
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
System.out.println("BeanPostProcessor 实现类构造函数...");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if("lagouBean".equals(beanName)) {
System.out.println("BeanPostProcessor 实现类 postProcessBeforeInitialization 方法被调用中......");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if("lagouBean".equals(beanName)) {
System.out.println("BeanPostProcessor 实现类 postProcessAfterInitialization 方法被调用中......");
}
return bean;
}
}
BeanFactoryPostProcessor
Clase de implementación de interfaz
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 16:56
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
System.out.println("BeanFactoryPostProcessor的实现类构造函数...");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory
beanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor的实现方法调用中......");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="lagouBean" class="com.lagou.LagouBean"/>
<bean id="myBeanFactoryPostProcessor"
class="com.lagou.MyBeanFactoryPostProcessor"/>
<bean id="myBeanPostProcessor" class="com.lagou.MyBeanPostProcessor"/>
</beans>
Caso de uso de análisis de código fuente de contenedor de IoC
/**
* Ioc 容器源码分析基础案例
*/
@Test
public void testIoC() {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("classpath:applicationContext.xml");
LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
System.out.println(lagouBean);
}
1. Analice si la creación de Bean es en el momento de la inicialización del contenedor o en el momento de getBean
De acuerdo con la depuración del punto de interrupción, encontramos que la creación del Bean se completa durante la inicialización del contenedor sin configurar la carga retrasada.
2. Analiza la llamada al constructor
A través de la observación anterior, encontramos que el tiempo de llamada del constructor está en el método de actualización de la clase AbstractApplicationContext ;finishBeanFactoryInitialization(beanFactory)
3. Analizar la invocación del método de inicialización afterPropertiesSet de InitializingBean
Observe la pila de llamadas
anterior a la observación, encontramos que InitializingBean
en afterPropertiesSet el tiempo de llamada al método está en el método de actualización de la clase AbstractApplicationContext de ;finishBeanFactoryInitialization(beanFactory)
4. Analizar la inicialización e invocación de BeanFactoryPostProcessor
Romper los puntos en el constructor y el postProcessBeanFactory
método respectivamente , observar la pila de llamadas y encontrar
BeanFactoryPostProcessor se inicializa en el método de actualización de la AbstractApplicationContext
clase ;invokeBeanFactoryPostProcessors(beanFactory)
método de actualización de laAbstractApplicationContext
clase de llamada postProcessBeanFactory de ;invokeBeanFactoryPostProcessors(beanFactory)
5. Analizar la inicialización e invocación de BeanPostProcessor
Romper los puntos en el constructor y el postProcessBeanFactory
método respectivamente , observar la pila de llamadas y encontrar
BeanPostProcessor se inicializa en el método de actualización de la AbstractApplicationContext
clase ;registerBeanPostProcessors(beanFactory)
método de actualización de laAbstractApplicationContext
clase de llamada postProcessBeforeInitialization de ;finishBeanFactoryInitialization(beanFactory)
método de actualización de laAbstractApplicationContext
clase de llamada postProcessAfterInitialization de ;finishBeanFactoryInitialization(beanFactory)
6. Resumen
De acuerdo con el análisis de depuración anterior, encontramos que varios puntos clave de sincronización de la creación del objeto Bean se llaman en
AbstractApplicationContext
el método de actualización de la clase . Se puede ver que este método es bastante crítico para la inicialización del contenedor Spring IoC . El resumen es el siguiente:
Tres, proceso principal de inicialización del contenedor Spring IoC
A partir de las muestras de análisis anteriores, el enlace clave de inicialización del contenedor Spring IoC en el AbstractApplicationContext#refresh()
proceso, vemos que el método de actualización pasa por alto el flujo principal del contenedor para crear los subprocesos específicos de los procesos corporales que se analizan detrás de nosotros.
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 第⼀步:刷新前的预处理
prepareRefresh();
/*
第一步:
获取BeanFactory;默认实现是DefaultListableBeanFactory
加载BeanDefition 并注册到 BeanDefitionRegistry
*/
ConfigurableListableBeanFactory beanFactory =
obtainFreshBeanFactory();
// 第三步:BeanFactory的预准备⼯作(BeanFactory进行一些设置,比如context的类加载器等)
prepareBeanFactory(beanFactory);
try {
// 第四步:BeanFactory准备⼯作完成后进⾏的后置处理工作
postProcessBeanFactory(beanFactory);
// 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接口的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
registerBeanPostProcessors(beanFactory);
// 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
// 第八步:初始化事件派发器
initApplicationEventMulticaster();
// 第九步:子类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
onRefresh();
// 第⼗步:注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean
registerListeners();
/*
第十一步:
初始化所有剩下的非懒加载的单例bean
初始化创建非懒加载方式的单例Bean实例(未设置属性)
填充属性
初始化方法调用(比如调用afterPropertiesSet方法、init-method方法)
调用BeanPostProcessor(后置处理器)对实例bean进行后置处
*/
finishBeanFactoryInitialization(beanFactory);
/*
第十二步:
完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件 (ContextRefreshedEvent)
*/
finishRefresh();
}
......
}
}
Si necesita esta versión completa de "Spring Advanced Source Notes", solo necesita apoyar mi artículo.
Mucho apoyo, puede obtener información gratis después de tres años consecutivos (promesa: 100% gratis)
Canal de inicio rápido: Agregar asistente VX: C18173184271 ¡Consígalo gratis! ¡Lleno de sinceridad! ! !