Hello, today I would like to share Spring IOC with you. Please take out your notebook and write it down.
The SpringIOC container initializes the body process
Spring IoC’s container architecture
IoC container is the core module of Spring, which abstracts object management and dependency management framework solution. Spring provides a number of containers, of which the BeanFactory is the top-level (root) container and cannot be instantiated. It defines a set of principles that all IoC containers must follow. Specific container implementations can add additional functionality, such as the common ApplicationContext. Its more specific implementation such as ClassPathXmlApplicationContext contains content, parse the XML and a series of AnnotationConfigApplicationContext is includes annotations and so on a series of content. The Spring IoC container inheritance system is smart enough to use whichever layer you need, rather than the full-featured one. The BeanFactory top-level interface method stack is as follows
BeanFactory container inheritance system
From its interface design, we can see that the ApplicationContext we always use inherits the BeanFactory sub-interface, ResourceLoader, MessageSource, etc., so it provides richer functionality.
Below we ClasspathXmlApplicationContext, for example, deep source of IoC container initialization process.
Bean lifecycle critical timing points
Create a class Bean, let it implement several special interfaces, and respectively in the constructor of interface implementation, interface method breakpoint, observe the thread call stack, analyze the Bean object creation and management key trigger time.
LagouBean class
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;
public class LagouBean implements InitializingBean{
/ * *
- The constructor
* /
public LagouBean(){
System.out.println(“LagouBean constructor… );
}
/ * *
- InitializingBean interface implementation
* /
public void afterPropertiesSet() throws Exception {
System.out.println(“LagouBean afterPropertiesSet…” );
}
}
BeanPostProcessor interface implementation class
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
System.out.println(“BeanPostProcessor implements class constructor… );
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {
if(“lagouBean”.equals(beanName)) {
System. Out.println (” BeanPostProcessor implementation class
PostProcessBeforeInitialization method is invoked in…” );
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {
if(“lagouBean”.equals(beanName)) {
System. Out.println (” BeanPostProcessor implementation class
PostProcessAfterInitialization method is invoked in…” );
}
return bean;
}
}
BeanFactoryPostProcessor interface implementation
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;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
System.out.println(“BeanFactoryPostProcessor implementation class constructor…” );
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println(“BeanFactoryPostProcessor implementation method call……” );
}
}
applicationContext.xm
The < beans XMLNS = “www.springframework.org/schema/bean…”
XMLNS: xsi = “www.w3.org/2001/XMLSch…”
xsi:schemaLocation=”
www.springframework.org/schema/bean…
www.springframework.org/schema/bean…
“>
<bean id=”myBeanFactoryPostProcessor”
class=”com.lagou.MyBeanFactoryPostProcessor”/>
IoC container source code analysis use cases
/ * *
- Ioc container source code analysis base case
* /
@Test
public void testIoC() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“classpath:applicationContext.xml”);
LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
System.out.println(lagouBean);
}
Analyze whether the Bean is created when the container is initialized or when the getBean is created
Based on breakpoint debugging, we found that without lazy loading, the Bean was created during container initialization.
Analyze constructor calls
Observe the call stack:
By the above observation, we found that the constructor calls time on AbstractApplicationContext class finishBeanFactoryInitialization refresh methods (the beanFactory);
Analyze the afterPropertiesSet initialization method call for InitializingBean
From the above observation, We found the afterPropertiesSet in the InitializingBean Method calls in AbstractApplicationContext timing and refresh methods finishBeanFactoryInitialization (the beanFactory);
Analyze BeanFactoryPostProcessor initialization and invocation
Observe the call stack at the break point at the constructor, postProcessBeanFactory method, Find spring BeanFactoryPostProcessor initialization AbstractApplicationContext class invokeBeanFactoryPostProcessors refresh methods (the beanFactory); PostProcessBeanFactory calls in invokeBeanFactoryPostProcessors AbstractApplicationContext classes refresh methods (the beanFactory);
Analyze BeanPostProcessor initialization and invocation
-
Observe the call stack at the break point at the constructor, postProcessBeanFactory method, Found BeanPostProcessor initialization in AbstractApplicationContext class registerBeanPostProcessors refresh methods (the beanFactory);
-
PostProcessBeforeInitialization calls in finishBeanFactoryInitialization AbstractApplicationContext classes refresh methods (the beanFactory);
-
FinishBeanFactoryInitialization postProcessAfterInitialization call in class AbstractApplicationContext refresh method (the beanFactory)
conclusion
According to the above debugging analysis, we found that Bean object creation of several key timing code level calls in the refresh method of AbstractApplicationContext classes, visible this method is critical for the Spring IoC container initialization, summary is as follows:
The Spring IoC container initializes the main process
By analysis, the Spring IoC container initialization key link in AbstractApplicationContext# refresh () method, we see the refresh method to overlooking the container to create the body of the process, main process under the specific subprocesses behind us again to discuss it.
BeanFactory creation process
Get the BeanFactory subprocess
BeanDefinition loads the parsing and registration subprocesses
This subprocess involves several key steps as follows
Resource location: The process of locating resources on the BeanDefinition. In plain English, this means finding the XML text that defines the Javabean information
And encapsulate it as a Resource object.
BeanDefinition loading: Represents the user-defined Javabeans as data structures inside the IoC container, the numbers inside the container
The data structure is the BeanDefinition.
Register the BeanDefinition into the IoC container
Process analysis
Step 1: subprocesses entry in AbstractRefreshableApplicationContext# refreshBeanFactory method
Step 2: In turn calls loadBeanDefinitions method of multiple classes – > AbstractXmlApplicationContext – > AbstractBeanDefinitionReader – > XmlBeanDefinitionReader is executed up to the doLoadBeanDefinitions method of XmlBeanDefinitionReader
Step 3: We focused on the registerBeanDefinitions method of the XmlBeanDefinitionReader class. There were several overloaded calls, and we settled on the last one
Here we focus on two areas: A createRederContext method, one is DefaultBeanDefinitionDocumentReader registerBeanDefinitions method of a class, enter the createRederContext method and have a look
As you can see, Spring first completes initialization of the NamespaceHandlerResolver. Let’s go back to the registerBeanDefinitions method and trace it and call it
DefaultBeanDefinitionDocumentReader# registerBeanDefinitions method
Enter the parseBeanDefinitions method
Enter the parseDefaultElement method
At this point, the registration process is over. We find that the so-called registration is to encapsulate the Bean information defined in the encapsulated XML into a BeanDefinition object and put it into a Map. The BeanFactory organizes these BeanDefinitions in a Map structure.
You can see in DefaultListableBeanFactory the definition of the Map
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new
ConcurrentHashMap<>(256);
Sequence diagram
Bean creation process
-
Through the analysis of the key time point at the beginning, we know that Bean created subprocess entrance in AbstractApplicationContext# refresh () method of finishBeanFactoryInitialization (the beanFactory)
-
Enter the finishBeanFactoryInitialization
Continue to enter the DefaultListableBeanFactory class preInstantiateSingletons method, we find the code for the following part, see factories Bean or common Bean, finally by getBean method for instance
Following along, we’ll go to the AbstractBeanFactory class’s doGetBean method, which has a lot of code, and we’ll go straight to the core
Then enter the AbstractAutowireCapableBeanFactory class method, find the following code section
Take a look at the doCreateBean method, where we focus on two key areas
1. Create the Bean instance without setting the properties
2. Populate the Bean with properties, call the initialization method, and apply the BeanPostProcessor post-processor
Well, today’s article is here, I hope to help you confused screen!