[spring source code analysis (1)]

Spring source code analysis [configuration file - complete bean object]

flow chart

insert image description here

analyze

First, how does spring load the configuration file into the application?
We have written configuration files such as xml or properties, so how is spring loaded? First of all, let’s look at it from here and think about a question. Each configuration file is different, so do we need to unify a specification to achieve reading different configuration file? Yes, spring provides such an abstract interface, BeanDefinitionReader ;
insert image description here
there are two subclasses under this interface, I believe everyone should understand it from the beginning of the name, here we should pay attention to the source code comments, BeanDefinitionReader is a reader; read these Bean definition information, it is a BeanDefinittion, so since it is a reader, just a reading, then think about a question? We define a bean in xml as follows:

<bean id=? class=? >
	<constructor name=username value=${
    
    username}>
	<constructor name=password value=${
    
    password}>
</bean>

Someone must have seen this way of writing, and then in the process of instantiation, what about this ${}? It will definitely become the corresponding value, otherwise there is no way to do it, so here, we need to know two questions that are often asked in interviews: the
difference between BeanFactoryPostProcessor and BeanPostProcessor? BeanFactoryPostProcessor : it handles BeanFactory, and BeanPostProcessor handles Bean;

Seeing this, let's recall again, after reading these bean definition information, it becomes a BeanDefinition, so who will handle
it?
insert image description here
So this process is handled by BeanFactoryPostProcessor , then there must be a subclass in this interface to handle these placeholders, so there is an abstract class called PlaceholderConfigurerSupport, its role is to solve the placeholder, see the explanation of the source code :
insert image description hereNext, instantiate the bean, then to the complete bean object, and then to destruction. In fact, it is what we are often asked in interviews, the life cycle of the bean? , there is a set of standards in the source code:
insert image description here
in AbstractApplicationContext , there is a very important method: refresh (); there are 13 methods in it;

@Override
	public void refresh() throws BeansException, IllegalStateException {
    
    
		synchronized (this.startupShutdownMonitor) {
    
    
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// Prepare this context for refreshing.
			//准备此上下文以进行刷新
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//告诉子类刷新内部 bean 工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//准备在此上下文中使用的 bean 工厂。
			prepareBeanFactory(beanFactory);

			try {
    
    
				// Allows post-processing of the bean factory in context subclasses.
				//允许在上下文子类中对 bean 工厂进行后处理。
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				//调用在上下文中注册为 bean 的工厂处理器。
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//注册拦截 bean 创建的 bean 处理器。
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// Initialize message source for this context.
				//为此上下文初始化消息源。
				initMessageSource();

				// Initialize event multicaster for this context.
				//为此上下文初始化事件多播器。
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				//初始化特定上下文子类中的其他特殊 bean。
				onRefresh();

				// Check for listener beans and register them.
				//检查侦听器 bean 并注册它们。
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//实例化所有剩余的(非延迟初始化)单例。
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//最后一步:发布相应的事件。
				finishRefresh();
			}

			catch (BeansException ex) {
    
    
				if (logger.isWarnEnabled()) {
    
    
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				//销毁已经创建的单例以避免悬空资源。
				destroyBeans();

				// Reset 'active' flag.
				//重置“活动”标志。
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
    
    
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				//重置 Spring 核心中的常见内省缓存
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

What we focus on is the finishBeanFactoryInitialization(beanFactory) method;
there is one in this method:
insert image description here
it is used to instantiate the remaining singletons. In this method, it will first go through such a process:
insert image description here
it will put beanDefinitionNames in a list In the collection, the loop traverses to complete the instantiation object, such as two beans in the xml file,
where getMergedLocalBeanDefinition first takes the BeanDefinition description information, first judges, if not, first creates CreateBean, and the real execution is doCreateBean , createBeanInstance instantiation Object, first create the constructor, and then instantiateBean instantiates the bean;
insert image description here
there is a ctor.newInstance in the Instantiateclass to start reflection, and the corresponding object is returned, and then enter the populatebean: its function is to fill in the attribute value of the object
insert image description here
and complete Aware, then before, and then the init method, that is, the invokeInitMethods method: insert image description here
the next step is to execute the after method, and the complete bean object is returned after execution; this is probably the case for this life cycle, and of course there will be destruction Status, destruction is not mentioned here.

The above one is probably the process of reading beans from configuration files and then instantiating and initializing beans in spring. It is very rough, but I hope to inspire everyone's general idea. After understanding the general idea, the remaining details will be slowly deducted. Bar;

Leave a small question: Where does the returned complete bean object end up?

Guess you like

Origin blog.csdn.net/qq_42990433/article/details/121654729