diagrama de flujo:
Hay 13 etapas
1. Etapa de configuración de la metainformación del bean
La información del frijol se define de 4 formas
- Forma API
- Método de archivo xml
- Método de archivo de propiedades
- Método de anotación
Método API:
Implementa la interfaz BeanDefinition. Hay 5 clases de implementación específicas:
- RootBeanDefinition: información de definición de root bean. Indica un bean sin un bean padre
- ChildBeanDefinition: información de definición de bean hijo. Necesita especificar el bean padre a través de la propiedad parentName
- GenericBeanDefinition: información de definición de bean genérico. Puede representar un bean sin un bean padre o un bean hijo con un bean padre. También hay un atributo padre.
- ConfigurationClassBeanDefinition: la información del bean definida por el método @bean en la clase de configuración.
- AnnotatedGenercBeanDefinition: información de bean definida por anotación
Simplemente crea una instancia directamente.
Manera xml:
<bean id="bean名称">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
</bean>
Finalmente, se analizará en el método de configuración de la API a través de la clase XmlBeanDefinitionReader
Método de archivo de propiedades:
employee.(class)=MyClass // 等同于:<bean class="MyClass" />
employee.(abstract)=true // 等同于:<bean abstract="true" />
employee.group=Insurance // 为属性设置值,等同于:<property name="group" value="Insurance" />
employee.usesDialUp=false // 为employee这个bean中的usesDialUp属性设置值,等同于:等同于:<property name="usesDialUp" value="false" />
Finalmente, se analizará en el método de configuración de la API a través de la clase PropertiesBeanDefinitionReader
Método de anotación:
@bean o @Compontent eventualmente se analizarán en el método de configuración de la API
2. Etapa de análisis de metainformación de frijoles
Hay tres formas principales de análisis de metainformación:
- análisis de bean de definición de archivo xml (XmlBeanDefinitionReader)
- El análisis del bean de definición de archivos de propiedades (PropertiesBeanDefinitionReader)
- Análisis de bean de definición de método de anotación (PropertiesBeanDefinitionReader)
Tres, registre el Bean en el contenedor.
Interfaz de registro de frijoles: BeanDefinitionRegistry (heredado AliasRegistry
)
Interfaz de registro de alias: AliasRegistry
Los primeros tres pasos ocurren cuando se crea el contenedor ioc, y los siguientes cuatro a diez pasos ocurren cuando getBean
Cuatro, fase de fusión de BeanDefinition
La definición de bean puede tener una relación padre-hijo de varios niveles, fusionada recursivamente en una RootBeanDefinition que contiene información completa.
El código fuente de la fusión es el siguiente:
Esta RootBeanDefinition se utilizará en las etapas posteriores, y el siguiente paso será verificar si el Bean dependiente debe cargarse, si no, omítalo (la imagen no se intercepta)
Cinco, fase de carga de la clase de frijol
Convierta el nombre de la clase del bean en un objeto de tipo Class.
El código fuente es el siguiente:
El método específico resolveBeanClass, profundice, puede ver que el objeto de clase final obtenido a través de Class.forName
Ahora que tiene el objeto de clase, puede comenzar a crear una instancia a través de la reflexión.
Seis, etapa de instanciación de Bean
(1) Antes de la instanciación
Se ejecutará el método postProcessBeforeInitialization de la clase que implementa la interfaz BeanPostProcesstor.
El código fuente es el siguiente:
Se puede ver que si se devuelve el bean, spring usará directamente el bean y omitirá la siguiente operación de creación de bean (este es un punto de extensión de spring)
(2) Instanciación
Este proceso usará la reflexión para llamar al constructor del bean para crear una instancia del bean y finalmente envolverlo en un BeanWrapper. (Modo decorador usado)
El código fuente es el siguiente:
El modo de estrategia se usa aquí , que se maneja en la clase SimpleInstantiationStrategy
Finalmente, el método newInstance (núcleo) de la clase llamada en el método InstantiateClass de la clase BeanUtils
Siete, procesamiento BeanDefinition fusionado
La clase de posprocesamiento realiza algún procesamiento de almacenamiento en caché, que es conveniente para su uso posterior
Principalmente realiza el procesamiento de devolución de llamada en la clase que implementa la interfaz MergedBeanDefinitionPostProcessor. Las clases de implementación incluyen principalmente:
- AutowiredAnnotationBeanPostProcessor almacena en caché los campos o métodos anotados con @Autowired y @Value para su uso posterior
- CommonAnnotationBeanPostProcessor almacena en caché campos o métodos anotados por @Resource, métodos anotados por @PostConstruct y métodos anotados por @PerDestroy
Ocho, etapa de asignación de atributos
(1) La etapa posterior a la instanciación
Spring llamará al método postProcessAfterInstantiation de la clase que implementa la interfaz InstantiationAwareBeanPostProcessor
Si devuelve falso, se omitirán los siguientes dos pasos de la asignación de atributos. Por lo que se puede utilizar para evitar la asignación de atributos.
(2) La etapa anterior a la asignación de atributos de Bean
Principalmente a través de @Autowire y otras anotaciones para generar el valor del atributo para su posterior asignación
Se puede ver que cuando tanto postProcessProperties como postProcessPropertyValues regresan vacíos, significa que el bean no necesita establecer propiedades y regresa directamente para ingresar a la siguiente etapa.
PropertyValues guarda la configuración de todos los valores de propiedad en el objeto de instancia de bean, por lo que podemos modificar el valor de PropertyValues en este postProcessProperties
La clase de implementación de InstantiationAwareBeanPostProcessor es la siguiente:
Lo más importante es la operación de inyección de estos dos valores de clase de implementación:
- AutowiredAnnotationBeanPostProcessor de inyección y el valor de un campo o método @Autowired marcado @Value
- CommonAnnotationBeanPostProcessor inyecta valores en campos o métodos anotados por @Resource
(3) Etapa de asignación de atributos de frijol
Haga circular PropertyValues
la información del valor del atributo en el procesamiento y establezca el valor del atributo en la instancia del bean invocando el método set mediante la reflexión.
Después de nueve curvas y dieciocho curvas, la última llamada es asignar valores a los campos mediante la reflexión en el método setValue de BeanWrapperImpl
Nueve, fase de inicialización de Bean
(1) Devolución de llamada de la interfaz Bean Aware
(2) Operación antes de la inicialización del Bean
Spring llamará al método postProcessBeforeInitialization de la clase de implementación que implementa la interfaz BeanPostProcessor.
La clase de implementación incluye mucho (no completa)
La clave es
- ApplicationContextAwareProcessor inyectará 6 Aware. Incluyendo: EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware. Porque solo el entorno ApplicationContext puede usar estos
- InitDestroyAnnotationBeanPostProcessor se usa para llamar a todos los métodos anotados con @PostConstrust
(3) Operación de inicialización de Bean
1. Llame al método afterPropertiesSet del Bean que implementa la interfaz InitializingBean
2. Invoque el método de inicialización del método init especificado al definir el bean .
Hay tres formas de especificar el método de inicialización:
- especificación del método xml <bean init-method = "nombre del método en bean" />
- El método @bean especifica @Bean (initMethod = "método de inicialización")
- El método api especifica beanDefinition.setInitMethodName (methodName);
(4) Operación después de la inicialización de Bean
Spring llamará al método postProcessAfterInitialization de la clase de implementación que implementa la interfaz BeanPostProcessor.
Diez, la etapa posterior a la inicialización del bean está completa
Para garantizar que se instancian todos los singleton no perezosos, teniendo en cuenta FactoryBeans
Entonces, después de que se complete la inicialización de todos los beans, Spring inicializará el método afterSingletonsInstanticated que implementa la interfaz SmartInitializingSingleton.
También incluye el propio BeanFactory.
El contenedor con ApplicationContext eventualmente llamará a preInstantiateSingletons internamente para activar la inicialización de todos los beans singleton.
11. Etapa de uso de frijoles
no hace falta decir que
12. La etapa previa a la destrucción de Bean
Hay tres formas de destruir el frijol:
- El método destroyBean de la clase AbstractAutowireCapableBean
- El método destroySingletons de la clase ConfigurableBeanFactory
- Método de cierre de ApplicationContext
La fase de destrucción de Bean se ejecutará en secuencia:
-
Sondeando la lista de beanPostProcessors, si es de tipo DestructionAwareBeanPostProcessor, se llamará a su método interno postProcessBeforeDestruction
-
Si el bean implementa la interfaz org.springframework.beans.factory.DisposableBean, se llamará al método de destrucción en esta interfaz
-
Llame al método de destrucción personalizado del bean
Spring llamará al método postProcessBeforeDestruction de la clase que implementa la interfaz DestructionAwareBeanPostProcessor
La clase de implementación es la siguiente:
La clave es:
- CommonAnnotationBeanPostProcessor Llamará a todos los métodos anotados @PreDestroy en el bean
Trece, etapa de destrucción de frijoles
Hay 3 formas de personalizar el método de destrucción:
- Especifique el método de destrucción en xml <bean destroy-method = "nombre del método en bean" />
- @Bean especifica el método de destrucción @Bean (destroyMethod = "método de inicialización")
- el método api especifica el método de destrucción beanDefinition.setDestroyMethodName (methodName);