Home >Java >javaTutorial >Spring source code analysis in java
<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 BeanDefinition
So what does it store? Let's take a look at its subclass AbstractBeanDefinition
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"
"Then initialize the reader in your own empty construction method!"
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!
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:
❝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()
❞ 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!❞
❝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);
starts to be executed. The first extension point appears here. When customizingbeanPostProcessorBeanFactoryPostProcessors
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, his callback timing is Spring calls it after reading all
BeanDefinition. Readers can use Baidu on their own for the specific usage!
❞ registerBeanPostProcessors(beanFactory);❝
❝ His purpose is to do an international operation, that is, i18n resource initialization
8).initApplicationEventMulticaster();❞
Event broadcaster(listen for events),(publish events),
Event listener
❞ onRefresh(); !11). finishBeanFactoryInitialization(beanFactory);❝❞
10). registerListeners();
❝
Register Spring event listener, as mentioned above, here is the initialization and registration of event listener
❞
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❞ 12). finishRefresh();beanPostProcessor
and other operations are all implemented here!
❞❝
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!