Recently, I have been cut off for some time. Because the company is busy, I made a share about Netty in the company on Friday. I will summarize and share it later.

In daily development, no matter what project you do, most of them cannot do without the Spring ecosystem. Therefore, many people are very interested in the underlying source code implementation of Spring, but some developers have never been in touch with the source code. In the process of looking at Spring source code is indeed and uncomfortable, why, most people look at the source code is basically debug bit by bit to see, and finally found that the more ridiculous, more and more deep, to finally catch up with JDK source code, also do not understand what is meant!

For learning source code, my view is, first to fully familiar with its use, think about if you implement, how you will achieve! With these ideas in mind, it’s much faster to look at the source code to validate your point of view than it is to lock in the source code yourself.

Also, I asked some readers and colleagues, I found that there are a lot of people, see source easily into a myth, is the first to see the source code is hard not to put, a detail have to understand, I’m not saying this to see what is wrong with the source code, but in did not have a global knowledge of the whole framework of cases, don’t do this, you should give a clear its broad Outlines, After dividing the function step by step to understand each function item! In this way, first of all, you have a vague understanding of the structure of the entire framework. Sometimes, even if you don’t know what the code is doing, you can vaguely guess it. Then, through debugging and your guesses, you can finally achieve twice the result with half the effort. Of course, this advice is only for students who have just started to see the source code, if you see a lot of source code, then you must have their own set of learning methods, if you can, you can communicate with the author in the message area or private chat!

In order to help new people or those who want to know more about the Spring source code, I will analyze some of the general logic of Spring, and the details will be shared by subsequent authors, but this article is just to let you know the whole skeleton of Spring!

2. Architecture legend

Spring lifecycle summary

This diagram basically generalizes the entire lifecycle of Spring initialization beans, including some of the most familiar lifecycle callbacks, as well as AOP or many big god has analyzed Spring to solve the cycle dependency level cache, it does not matter, behind the author will take the source code step by step analysis:

Third, source code analysis

1. Prepare

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

Above this line of code I estimate that people who have used Spring are particularly familiar with, if not familiar with, then I advise you to learn to use, and then go to some of the source code of the underlying logic!

Let’s see how he instantiates the bean step by step, takes over the bean, and then executes the various life cycle classes! Let’s take a guess. When Spring reads these beans, the information about the beans must be stored in an entity. What is that entity? This class is BeanDefinition so what does it store? So let’s take a look at a subclass of AbstractBeanDefinition and if you’re interested click on it, just to give you a sense of what a BeanDefinition is:

image-20200725135718518

Define this similar to such attribute values, of course the author do the interception of the handful of attribute, the attribute of it far more than this, it is the purpose of the bean is instantiated, the data you need don’t need to go through his own reflection, but rather to Spring when initialize all read, need to take it from there, After understanding the concept of BD, are we confused? Where does he store it after he reads it? The answer is to store it in the beanFactory, so Spring will definitely implement a bean factory first! Into AnnotationConfigApplicationContext inside, you will send is not initialized, the initialization? As is known to all, a class initialized again will first load the superclass constructor, so we need to have a look at its superclass GenericApplicationContext:

public GenericApplicationContext(a) {
    // Initialize the bean factory
    this.beanFactory = new DefaultListableBeanFactory();
}
Copy the code

Sure enough that I expected, it then the parent class created inside the bean factory, factory had, we continue to go back to AnnotationConfigApplicationContext inside look down: found it calls a this (), it calls his empty constructor, so, we enter a look at:

public AnnotationConfigApplicationContext(a) {
    // Initialize the reader
    this.reader = new AnnotatedBeanDefinitionReader(this);
    // Initialize the scanner
    this.scanner = new ClassPathBeanDefinitionScanner(this);
} Copy the code

At this point we can see the contrast above: the bean factory has been initialized

image-20200725140629568

Then there is an initializer in the empty constructor itself!

image-20200725140742200

That we continue to go back to AnnotationConfigApplicationContext inside the constructor:

   / * ** create a new AnnotationConfigApplicationContext, derived from the given annotated class bean definition* And automatically refresh the context.  * @param annotatedClasses one or more annotated classes,
 * e.g. {@link Configuration @Configuration} classes * /  public AnnotationConfigApplicationContext(Class
             ... annotatedClasses) {  // Read several of Spring's built-in class files to convert to BD and initialize the bean factory  this(a); // This step is to register the Config class and resolve bd  register(annotatedClasses);  // This step is the core, the understanding of Spring is all in this step, this step can be said to understand Spring 70%  // Do a series of operations internally, such as calling the bean factory's post-processor instantiation class, calling the post-processor's pre-processing, and registering event listeners  // Completes the lifecycle of a class from a class file to a bean  refresh();  } Copy the code

The next step is to call the register method. What do you do? Imagine that sometimes our auto-scan configuration is configured using the annotation @ComponentScan(“com.service”). Where is this class? By the way, it is generally in the configuration class!

@Configuration
@ComponentScan("com.service")
public class SpringDebugConfig {}
Copy the code

In order to know which classes we want to scan, we have to parse the BeanDefinition of the configuration class so we can get the package we want to parse. This method not only resolves the scanned package, but also other things that we won’t cover in this article!

2. Core functions

Well, further down we know that we’re going to scan those classes under the package to make them beans, so we go down to Refresh (); This method is the core method of the entire Springbean initialization. It can also understand Spring instantiation, callback, etc.

After coming in, we did a method by method analysis of what function, the first is:

1). prepareRefresh();

This is a series of assignment operations before refreshing the bean factory, mainly for the previously created Spring factory many properties are empty, this way is to do some initialization value operations for it!

2). obtainFreshBeanFactory()

Tell the subclass to refresh the internal bean factory to check whether the bean factory exists, determine whether the current bean factory has been refreshed only once, report an error many times, return the currently used bean factory, create a new factory when the step is XML and return

3). prepareBeanFactory(beanFactory);

BeanPostProcessor (BeanPostProcessor, BeanPostProcessor, BeanPostProcessor, BeanPostProcessor, BeanPostProcessor, BeanPostProcessor)

4). postProcessBeanFactory(beanFactory);

Allows post-processing of bean factories in context subclasses to do some custom processing after the BeanFactory is ready! But notice, when you click on an empty method, what does an empty method mean? Meaning Spring developers want callers to customize extensions to use!

5). invokeBeanFactoryPostProcessors(beanFactory);

Actually believe that the name, most readers are able to guess, his aim is to scan the configuration class bd to register to the factory, after the scan is complete, start to perform all BeanFactoryPostProcessors, here the first extension points, Custom implementation BeanFactoryPostProcessors, the callback time he is in the Spring after reading all the BeanDefinition calls, the use of the specific readers to baidu!

6). registerBeanPostProcessors(beanFactory);

This is the post-processor that registers the bean which is the implementation of beanPostProcessor and it has its own built-in processor notice that it’s not called here, it’s just registering the hu processor in the bean factory! Have you used the beanPostProcessor interface extension point? This is the method in which the Spring factory is registered. Notice, of course, that the Spring factory is registered, not executed! Remember there is no execution!

7). initMessageSource();

Well, this is a method that the author is not going to go into, because it goes against the intent of this article, which is to do an internationalization operation which is the resource initialization of I18N, right

8).initApplicationEventMulticaster();

Spring provides an encapsulation for event programming. Generally speaking, events are divided into three roles: event broadcaster (event publishing), event listener (event listening), and event source (specific event information). The purpose of this method is to initialize the event broadcaster!

9). onRefresh();

Here is another extension point, the internal method is empty and Spring does not implement it for the caller to implement!

10). registerListeners();

Register the Event listener for Spring, as mentioned above. Here we initialize and register the event listener

11). finishBeanFactoryInitialization(beanFactory);

This method is an important one in order to instantiate all remaining (non-lazy initialization) singletons. The bean instantiation, injection, resolution of loop dependencies, callback to beanPostProcessor and so on are all implemented here!

12). finishRefresh();

The final step: Publish the corresponding event. Events built into Spring

So far we have completed the entire lifecycle skeleton of Spring initialization. Here the author does not delve into the implementation of Spring, but just gives readers a framework to help clarify the context of Spring, which needs to be filled by the reader! Now if you go back and look at the picture, isn’t it much clearer? I’m going to put that diagram out again so you don’t have to turn it over again!

Spring lifecycle summary

Well, today’s article here is also over, the author of leisure time sorted out a material, we are interested in can get next!

If the understanding of the article is wrong, welcome big men private chat correction! Welcome to pay attention to the author’s public number, progress together, learn together!

Welcome to pay attention to the author, learn and progress together