Personal summary in 2019-Spring IOC initialization process

I just want the big waves to wash away the sand, and not to pass by

First, let me talk about my personal understanding of the spring container (there is a project in all projects on the spring official website called spring springframework, or spring framework for short)

The spring framework is a container that is used to store the objects we hand over to spring for management, referred to as beans.

The core modules are mainly divided into IOC and AOP (web, test, etc.)

IOC is also called DI inversion of control and dependency injection. The main idea is decoupling. Inversion of control mainly means that we used to need programmers to create an object through the new keyword and maintain the dependencies between the objects. After IOC, we only need to give this object to the container. , It will help us create and maintain dependencies between objects.

And AOP, aspect-oriented programming, separates and encapsulates the public modules in our project into a single module. This module is called aspect, which is also born for decoupling in thought.

We use aop in two ways, the first is spring aop configured through xml files, and the second is enabled by @Aspect annotation.

There should be connection points (expression execution, within, etc.), cut points, notifications (before, after, surround, exception), and weaving in an aspect of ours.

The difference is that spring aop is dynamically woven at runtime. Aspect is statically woven at compile time. Which one depends on personal preference

Then AOP is dependent on IOC, so much IOC and AOP are two parts (the official website is separated), it is better to say that AOP is a part of IOC, because the life cycle of springbean is accompanied by the analysis of AOP (for example, the first step is through A post processor of BeanPostProcessor is used to fill a collection of objects that need to be proxied to prepare for later enhancements).

 The first thing I want to introduce is the BeanDefinition object. The ultimate goal of Spring is to convert Java Object ---> BeanDefinition ---> Spring Bean

 Therefore, the BeanDefinition object and its attributes and subclasses are very important. Introduce this picture from spring's official website again

The Java Object fills the meta-attributes through the Spring container and becomes a BeanDefinition object. After a whole life cycle, the Java Object becomes a Spring Bean for you to use. The process and implementation do not require us to do it.

The second point introduced is the extension point of the Spring container.

The extension points are as follows

InitializingBean Spring Bean, one of the life cycle callback interfaces, Spring Web MVC initializes and fills the Map property to implement this interface 

One of the callback interfaces for the completion of the SmartLifecycle Spring container initialization 

ImportSelector Spring Boot's automatic configuration (non-Spring's automatic assembly) implements this interface

ImportBeanDefinitionRegistrar MyBatis integrates Spring to realize the process of scanning the MapperScanner property of this interface-->Proxy Object-->Spring Bean

BeanFactoryPostProcessor BeanFactory post processor

BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor BeanFactory factory post processor

ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor BeanFactory factory post processor built-in only implementation class
Next look at the execution timing of these three classes (implementation classes) in the source code

new AnnotationConfigApplicationContext(AppConfig.class);
this();//第一步 初始化 beanFactory 工厂
register(annotatedClasses); // 注册配置类
refresh(); // 如下 
//准备工作包括设置启动时间,是否激活标识位,初始化属性源(property,source)配置
prepareRefresh();
//获取到 DefaultListableBeanFactory 对象
//已经注册过了
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//传入 beanFactory 调用处理器对Bean工厂做一些标准的配置
prepareBeanFactory(beanFactory);
//空方法
postProcessBeanFactory(beanFactory);
//执行自定义的BeanFactoryProcessor和内置的BeanFactoryProcessor
// 完成扫描和解析 object --  > beanDefinition
invokeBeanFactoryPostProcessors(beanFactory);//开始执行BeanFactory的后置处理器扩展点(策略模式)
registerBeanPostProcessors(beanFactory);//开始执行BeanFactory 的后置处理器
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
//实例化所有的非懒加载单例
//bean生命周期
finishBeanFactoryInitialization(beanFactory);
finishRefresh();

invokeBeanFactoryPostProcessors(beanFactory);

The execution timing of the BeanDefinitionRegistryPostProcessor BeanFactory's post processor that implements this interface

1. First execute the post processor of the BeanFactory that implements the interfaces of BeanDefinitionRegistryPostProcessor and PriorityOrdered

2. Then execute the post processor of the BeanFactory that implements the BeanDefinitionRegistryPostProcessor and Ordered interfaces

3. Finally execute the post processor of the BeanFactory that implements the interface of BeanDefinitionRegistryPostProcessor

Implementation timing of the BeanFactoryPostProcessor BeanFactory's post processor that implements this interface

4. First execute the post processor of the BeanFactory that implements the BeanFactoryPostProcessor and PriorityOrdered interfaces

5. Then execute the post processor of the BeanFactory that implements the BeanFactoryPostProcessor and Ordered interfaces

6. Finally execute the post processor of the BeanFactory that implements the BeanFactoryPostProcessor interface

When executing these BeanFactory post-processors, Spring will also execute a Bean post-processor mainly to complete the merger of the parent and child BeanDefinition, so the first point introduced is very important.

ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor What does Spring do?

Complete the second scan to parse all the annotations contained in the configuration class @Import @PropertySource @ComponentScans @Bean

And the class that implements the ImportSelector interface and the ImportBeanDefinitionRegistrar interface

Encapsulated into BeanDefinition and registered in BeanDefinitionMap.

ConfigurationClassPostProcessor implements the BeanFactoryPostProcessor post processor What did Spring do

Mainly to complete the CGLIB enhancement for the configuration class. Let's see the following

@ComponentScan("org.springframework.test2")
@Configuration
public class AppConfig {
   
   @Bean
   public B b(){
      System.out.println("===b===");
      return new B();
   }

   @Bean
   public  A a(){
      System.out.println("===a===");
      b();
      return new A();
   }

}

Why does the annotation @Configuration only print a and b once, but not b twice.

Object a and object b are both singletons, why is it initialized twice?

The annotation @Configuration added will be parsed by the ConfigurationClassPostProcessor class and CGLIB proxy will be performed.

But why is b only initialized once after CGLIB (Spring cyclic dependency principle)

 registerBeanPostProcessors(beanFactory);

The execution timing of the post processor of the BeanPostProcessor Bean that implements this interface is accompanied by the life cycle of the Bean

1. First add the post processor of the Bean that implements the BeanPostProcessor and PriorityOrdered interfaces

2. Add the post processor of the Bean that implements the BeanPostProcessor and Ordered interfaces

3. Finally add the post processor of the Bean that implements the BeanPostProcessor interface

Bean's post processor execution timing

1. Determine whether the bean being instantiated needs to be proxied, if necessary, add it to a collection and return empty

InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation{return null}

2. Inferred construction method

SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors{return null}

spring-ioc-inferred constructor-manual assembly   spring-ioc-inferred constructor-automatic assembly

3. Merge parent and child BeanDefinition

MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition

4. Circular dependency, exposing a factory, and obtaining Bean instances through the factory (the reason for exposing the factory is to assemble attributes for the proxy object) SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference

spring-ioc-cyclic dependency

5. Attribute injection, to determine whether the current object allows attribute injection (default is true) InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

6. Attribute injection manual injection @Autowired and @Resource automatic injection based on Java reflection mechanism (one of the injection models) based on Java introspection mechanism

The search method of @Autowired and @Resource in the source code @Autowired first finds according to the type, puts the found type in a collection, and then matches by name in the collection, and vice versa @Resource

Why @Autowired and @Resource are not automatic injection please see

spring-ioc-automatic assembly

7. Implement the Aware interface and implement the Before method of BeanPostProcessor by ourselves

BeanPostProcessor#postProcessBeforeInitialization

8. Dynamic proxy Proxy, and our own implementation of the After method of BeanPostProcessor

BeanPostProcessor#postProcessAfterInitialization

There are three ways to execute Bean life cycle callbacks

First, initialize the callback. The order of execution can exist for all three types. Annotation>Interface>xml

The first xml-based <bean init-method="">

The second type implements InitializingBean based on the interface

The third is based on annotation @PostConstruct

Similarly destroy callback

<bean destroy-method="">  

DestroyBean implements DisposableBean

@PreDestroy

Execute Spring container life cycle callback

Classes that implement the SmartLifecycle interface and classes that implement the Lifecycle interface

interface Lifecycle{

void start();

void stop();

boolean isRunning();

}

interface SmartLifecycle {

isAutoStartup ();

void stop(Runnable callback);

int getPhase();

}

So far, the life cycle of Spring Bean ends. The initialization of the Spring container is complete.

To sum it up, there are two parts

The first part BeanFactoryPostProcessor BeanFactory's post processor completes half of the initialization of the Spring container

The second part of the BeanPostProcessor Bean post processor completes the other half of the initialization of the Spring container and the life cycle of the Bean

Guess you like

Origin blog.csdn.net/qq_38108719/article/details/103384787