Home  >  Article  >  Java  >  Spring source code analysis in java

Spring source code analysis in java

WBOY
WBOYforward
2023-04-30 23:13:05775browse

Source code analysis

1. Preliminary preparation

<code>/**<br> * spring debug<br> * @author huangfu<br> */<br>public class SpringDebug {<br>public static void main(String[] args) {<br>		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(SpringDebugConfig.class);<br>	}<br>}<br></code>

I guess everyone who has used Spring is special about the above line of code Familiar with it, if you are not familiar with it, then I advise you to learn to use it first, and then delve into the underlying logic of some source codes!

Let’s take a look at how he instantiates the bean step by step, takes over the bean, and then executes various life cycle classes! Let's make a guess first. When spring reads these beans, the information about the beans must be stored on a certain entity. So what is this entity? This class is BeanDefinitionSo what does it store? Let's take a look at its subclass AbstractBeanDefinition

Spring source code analysis in java

which defines attribute values ​​similar to this. Of course, the author has intercepted a few attributes. There are far more properties than this. Its purpose is that when the bean is instantiated, the required data does not need to be obtained through reflection by yourself. Instead, it is read all during Spring initialization. You can just get it from here when needed. , after understanding the concept of bd, are we confused? Where does it store it after reading it? The answer is to store it in the beanFactory, so Spring will definitely implement a bean factory first when initializing! Entering AnnotationConfigApplicationContext, you will find that it has not been initialized. Where is it initialized? As we all know, when a class is re-initialized, the constructor of the parent class will be loaded first, so we need to take a look at its parent class GenericApplicationContext:

<code>public GenericApplicationContext() {<br>    //初始化bean的工厂<br>    this.beanFactory = new DefaultListableBeanFactory();<br>}</code>     

As expected, it Create a bean factory in the parent class. With the factory now available, we continue to go back to AnnotationConfigApplicationContext and look down: we find that it calls a this(), indicating that it calls its own empty constructor, so, Let's go in and take a look:

<code>public AnnotationConfigApplicationContext() {<br>    //初始化读取器<br>    this.reader = new AnnotatedBeanDefinitionReader(this);<br>    //初始化扫描器<br>    this.scanner = new ClassPathBeanDefinitionScanner(this);<br>}</code>   

"At this point we can look at the picture above: the bean factory is there during initialization"

Spring source code analysis in java      

"Then initialize the reader in your own empty construction method!"

Spring source code analysis in java

Then let's continue back to AnnotationConfigApplicationContext In the construction method:

<code>   /**<br>	 * 创建一个新的AnnotationConfigApplicationContext,从给定的带注释的类派生bean定义<br>	 * 并自动刷新上下文。<br>	 * @param annotatedClasses one or more annotated classes,<br>	 * e.g. {@link Configuration @Configuration} classes<br>	 */<br>public AnnotationConfigApplicationContext(Class>... annotatedClasses) {<br>//读取Spring内置的几个的class文件转换为bd  然后初始化bean工厂<br>this();<br>//这一步就是将配置类Config进行了注册并解析bd<br>		register(annotatedClasses);<br>//这一步是核心,Spring的理解全在这一步,这一步理解了也就可以说将Spring理解了70%<br>//内部做一系列的操作如调用bean工厂的后置处理器   实例化类  调用 后置处理器的前置处理   初始化类  调用后置处理器的后置处理 注册事件监听等操作<br>//完成一个类从class文件变为bean的生命周期<br>		refresh();<br>	}</code>     

The next step is to call the register method. What to do? Just imagine, sometimes our automatic scanning configuration is configured through the annotation @ComponentScan("com.service"). Where is this class usually located? By the way, it's usually in the configuration class!

<code>@Configuration<br>@ComponentScan("com.service")<br>public class SpringDebugConfig {}</code>     

In order to know that we want to scan the classes under those packages, we must first parse the BeanDefinition of the configuration class, so that we can obtain the packages we want to parse later. Of course, this method It not only parses the scanned packets, but also parses other things, which I won’t explain in this article!

2. Core functions

Okay, if we go further down, we will know that we are about to scan the classes under those packages and turn them into beans, then we will continue to go down, Go to refresh();This method is amazing. It is the core method of the entire Springbean initialization. If you understand it, you can understand Spring's instantiation, callbacks and other issues. Let's go in and take a look:

After coming in, we analyze what functions are done method by method. The first is:

1). prepareRefresh();

Here is the refresh The series of assignment operations before the bean factory are mainly because many properties of the Spring factory created earlier are empty. This method is to do a series of initialization value operations for it!

❞                                         ). obtainFreshBeanFactory()
❝      
Tell the subclass to refresh the internal bean factory. Detect whether the bean factory exists. Determine whether the current bean factory has only been refreshed once. If an error is reported multiple times, the currently used bean factory will be returned. When this step is xml, a new factory will be created and returned
❞     

3). prepareBeanFactory (beanFactory); The beanFactory internally registers some of its own built-in Bean post-processors, which are usually called BeanPostProcessor. This method is actually also a re-initialization of the factory!
❞            
4). postProcessBeanFactory(beanFactory);
❝  

Allows post-processing of the bean factory in the context subclass, which is used to do some customization after the BeanFactory preparation work is completed Processing! But note that the method you click on is an empty method. What does the empty method mean? It means that Spring developers want callers to use custom extensions!

❞                                                                          invokeBeanFactoryPostProcessors(beanFactory);
❝                                                                                                                      invokeBeanFactoryPostProcessors(beanFactory); bd is registered in the factory. After the scan is completed, all
BeanFactoryPostProcessors
starts to be executed. The first extension point appears here. When customizing

BeanFactoryPostProcessors, his callback timing is Spring calls it after reading all BeanDefinition. Readers can use Baidu on their own for the specific usage! ❞                                                                                             registerBeanPostProcessors(beanFactory);❝           

Here is the post-processor of the registered bean, that is, the implementation of beanPostProcessor and its own built-in processor Note The processor is not called here, but the Hu processor is registered into the bean factory! I wonder if you have used the extension point of the
beanPostProcessor
interface? It is registered into the Spring factory in this method. Of course, please note that it is only registered and not executed! Remembering does not execute!
❞                                                              initMessageSource();

❝                                                                                                                                         His purpose is to do an international operation, that is, i18n resource initialization❞      

8).initApplicationEventMulticaster();
❝    
Spring provides us with event programming Encapsulation, generally speaking, events are divided into three roles,
Event broadcaster

(publish events),

Event listener
(listen for events),
Event source
( Specific event information) three roles, the purpose of this method is to initialize the event broadcaster!
❞                                                                                                                                                                                onRefresh(); !

❞           10). registerListeners();❝   Register Spring event listener, as mentioned above, here is the initialization and registration of event listener❞          

11). finishBeanFactoryInitialization(beanFactory);
❝  
This method is a key point, it is to instantiate all remaining (non-lazy initialization) singletons. What we call bean instantiation, injection, resolving circular dependencies, callback

beanPostProcessor

and other operations are all implemented here!
❞        
12). finishRefresh();

❝      

Last step: Publish the corresponding event. Spring's built-in events
❞          

The above is the detailed content of Spring source code analysis in java. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete