[Startup process of Spring container]

Spring container startup process

Spring has two very important steps in the initialization process, container initialization and refresh.

Initialization process

Insert image description here

  • If you want to generate bean objects, you need a beanFactory factory (DefaultListableBeanFactory)
  • If you want to read a class with specific annotations (such as @Service, @Repository) and convert it into a BeanDefinition object (BeanDefinition stores all characteristic information of the bean object, such as whether it is a singleton, whether it is lazy loading, factoryBeanName, etc.), Then you need an annotation configuration reader (AnnotatedBeanDefinitionReader)
  • If you want to scan the user-specified package directory to find bean objects, you need a path scanner (ClassPathBeanDefinitionScanner)

When loading the configuration file, Spring creates a BeanFactory factory, then fills the BeanDefinition of the factory with configuration information, and creates related Bean instances based on this information. When creating a Bean instance, Spring adopts a lazy initialization strategy, that is, it will only be initialized when the Bean instance is needed.

The process of registering BeanDefinition mainly includes parsing configuration files, scanning annotations, parsing Java Config, etc. When parsing the configuration file, Spring will parse it according to the syntax rules of the configuration file and encapsulate the parsing result into a BeanDefinition object. When scanning annotations, Spring will scan the classes under the specified package and encapsulate the classes with the specified annotations into BeanDefinition objects. When parsing Java Config, Spring will parse it according to the syntax rules of the Java Config configuration file and encapsulate the parsing result into a BeanDefinition object.

ClassPathBeanDefinitionScanner is a tool class of the Spring framework that can search for beans under the specified package path. It scans all eligible classes and registers them as beans for use in subsequent operations. Using this tool class, you will first create a BeanDefinitionRegistry object, then create a ClassPathBeanDefinitionScanner object, and set its scan path and filter. Finally, call the scan method to start scanning. After the scanning is completed, ClassPathBeanDefinitionScanner will automatically register the scanned classes into BeanDefinitionRegistry. After completing the registration, you can use Spring's BeanFactory to obtain the specified bean.

refresh process

Insert image description here
refresh() is mainly used to refresh containers. Each container in Spring will call the refresh() method to refresh. The refresh() method mainly completes the following steps:

(1) Prepare the container, such as initializing environment variables, registering system event listeners, etc.

(2) Create or obtain a BeanFactory instance. If a BeanFactory instance is passed in during creation, that instance is used; otherwise, a new BeanFactory instance is created based on the configuration file.

(3) Make some necessary settings for BeanFactory, such as setting ClassLoader, setting BeanPostProcessor, etc.

(4) Post-processing of BeanFactory can be used to extend the functions of BeanFactory.

(5) Execute the implementation class of the BeanFactoryPostProcessor interface to perform post-processing on the BeanFactory.

(6) Register all BeanPostProcessor implementation classes.

(7) Initialize MessageSource for internationalization processing.

(8) Initialize the event broadcaster for sending and receiving events.

(9) Notify all registered listener containers that they have been initialized.

(10) Release resources when closing the container.

(11) Register event listener.

(12) Complete the initialization of BeanFactory, including creating instances, injecting dependencies, executing initialization methods, etc.

(13) Complete the initialization of the container, release resources, etc.

//refresh()的简略源码:
public void refresh() throws BeansException, IllegalStateException {
    
    
	synchronized (this.startupShutdownMonitor) {
    
    
		// 1. 刷新前的预处理
		prepareRefresh();
		// 2. 获取 beanFactory,即前面创建的【DefaultListableBeanFactory】
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		// 3. 预处理 beanFactory,向容器中添加一些组件
		prepareBeanFactory(beanFactory);
		try {
    
    
			// 4. 子类通过重写这个方法可以在 BeanFactory 创建并与准备完成以后做进一步的设置
			postProcessBeanFactory(beanFactory);
			// 5. 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器
			invokeBeanFactoryPostProcessors(beanFactory);
			// 6. 注册 BeanPostProcessors,bean 后置处理器
			registerBeanPostProcessors(beanFactory);
			// 7. 初始化 MessageSource 组件(做国际化功能;消息绑定,消息解析)
			initMessageSource();
			// 8. 初始化事件派发器,在注册监听器时会用到
			initApplicationEventMulticaster();
			// 9. 留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑,web 场景下会使用
			onRefresh();
			// 10. 注册监听器,派发之前步骤产生的一些事件(可能没有)
			registerListeners();
			// 11. 初始化所有的非单实例 bean
			finishBeanFactoryInitialization(beanFactory);
			// 12. 发布容器刷新完成事件
			finishRefresh();
		}
		catch(){
    
    ...}
        finally{
    
    ...}
	}
}

Guess you like

Origin blog.csdn.net/java_wxid/article/details/132888465