First, the opening question

Is a Spring Bean a Java object? Is an object a Spring Bean?

With this question in mind let’s review the Spring lifecycle process to see exactly what a class does in Spring!

Let’s start with a piece of code!

image-20200922221511683

Of course, anyone who has ever used Spring should know that the EmailServiceImpl is automatically injected into any object obtained from the Spring container!

But the same point is that both of them are Java objects that are loaded into the JVM, so at least we can now answer the question:

The SpringBean must be a Java object; But a Java object is not necessarily a SpringBean!

Should we assume that only spring-managed classes can be called beans and everything else objects? So how does Spring convert a class from an ordinary class to a Spring Bean? What steps did he go through? Let’s explore!

Bold guesses about the Spring lifecycle

Here to share a reading source tips: catch big release small, even meng with guess! Eight secret words, we are in the process of reading the source code, because you know, the excellent framework, each one is open source, the source of the system is extremely complex, we can’t please everyone, so in the process of the source must not be entangled, details must be first out a general idea of the framework and general framework of system, and to get those details, Its efficiency will be much better, secondly in the process of looking at the source code, we must be bold to think, to guess, if this function let you write yourself, how will you achieve!

Today we will learn the life cycle of Spring bean according to this eight-word mantra. From what we have learned before, Spring has roughly the following functions:

  1. He will help us automatically create objects and save them!
  2. He will help us complete the property fill!
  3. If we set up Aop functionality, it will help us automatically proxy, implement the aspect functionality!

From ordinary use, we can at least know the above three points, if you let yourself to achieve, will be how to achieve?

  • First of all, since it can help us to create the object, so it must be created by reflection, by reflection, must not get around to using the Class object, so how do we get the Class object? To scan the project, slice the annotated Class file under the specified package to get the Class name, load the Class name through reflection, and reflection creates the Java object!
  • We’re going to finish filling in the properties, and for convenience and performance, I’m definitely going to save these created objects, no doubtMapContainers are perfect!
  • After we create an object, reflection gets the property inside. If we need to fill, we first go to the container we saved before to get the property. Reflection creates the dependent property, and then fills the object and saves it in the container, thus completing the property injection!
  • After the property is filled, we compare the current object with Aop logic to determine whether it needs proxy. If it does not need proxy, it will be created and saved into the Map container. If it needs proxy, it will carry out the current classjdkorcglibThe proxy is then saved into the container!

As a result, we have implemented all the procedures for managing a Bean in Spring. Let’s draw a picture. It looks like this!

image-20200922230911796

The whole process looks pretty clean, with scanning, creating, injecting, proxying, and saving all in one place, but Spring’s implementation is far more complicated than what we’ve implemented ourselves!

Spring’s lifecycle process

Spring’s authors hope that the next time Spring starts managing a Bean, it wants Spring users to have a hand in every step of Spring’s process of turning a class Object into a Java Object.

For example, we bought a new house, this house needs to decorate, you go to decorate a true professional enough, can’t please everyone, so it is we have to find a decorate a company to help us to decorate bridal chamber, then decorate decorate, start painting in advance good drawing but in decorating a process, in order to make their new home more warm, you You want to hang some murals on the walls, but they’re not on the drawings! So you look for decoration company, decoration company requirements in the new home wall hanging a few murals! Decorate a company after accepting your request, the worker that orders to decorate goes to hang murals on the wall for you outside drawings, decorate again next!

The above story has several characters. Let’s contrast it with Spring!

  • You: Represent the user of the framework!
  • New house: on behalf of a Class file, you can also decorate, but not professional enough, so to the decoration company! Creating your own objects might be a bit cumbersome to use, so we’ll leave it to the Spring container!
  • Decoration company: represents the Spring container!
  • Drawings: represent preset steps, steps that Spring already has!
  • Worker: All the interfaces Spring provides! We can do all kinds of custom configurations through the interface provided by the Spring factory!

The above short story roughly describes the core idea of the Spring life cycle! When Spring instantiates a Class file into a concrete Spring Bean, it provides various interfaces that we implement ourselves! Then call different interfaces at different times during the instantiation process! Complete the creation of Spring’s entire life cycle!

The Spring lifecycle is roughly divided into the following sections!

  1. Scan the project and convert the Class file in the specified directory of the project into a Class object!
  2. Read the Class object property wrapped asBeanDefinitionAnd save it in a Map! (It’s easy to understand that he created this class to make it easier to create or read information about it later.)
  3. Convert all classes toBeanDefinitionAfter saving, the first callback interface is invokedBeanFactoryPostProcessor#postProcessBeanFactory()!
    • It is called when the scanned Class file is converted toBeanDefinitionAfter that, we can get all of them through the callback methodBeanDefinitionAnd all subsequent operations on Class are based onBeanDefinitionOperation, so we can modify it to change the subsequent process!
  4. The current object to be created is fetched from the current container object. When the retrieved object is null, the object is created!
  5. Verify that the class is excluded, is being created, has a @dependson annotation, is a singleton, etc.
  6. Once verified, start creating the object through reflection!
  7. mergeBeanDefinitionThis refers to the parent-child container concept used in previous versions of Spring.
  8. Determine if the current object is a singleton, supports circular references, is being created, etc.
  9. Perform the second interface callbackInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()Methods!
    • Its execution time is after the instantiation is complete, and before the property is filled, its return value is a Boolean value. When false is returned, no automatic property is filled!
  10. Perform the third interface callbackInstantiationAwareBeanPostProcessor#postProcessProperties()Methods!
    • Its execution time is, after instantiation, after property fill check, before property fill! It returns a property, and subsequent property populations use the value returned by this method! We can change the injected value of the corresponding Bean in this method!
  11. Fill properties into objects!
  12. Invoke the fourth callback interfaceBeanNameAware#setBeanName()Methods!
    • Call timing: after the property is filled, before the initialization method is called; Its function is to get the bean’s Name!
  13. Invoke the fifth callback interfaceBeanClassLoaderAware#setBeanClassLoader()
    • Call timing:BeanNameAwareAfter that, its function is to pass in the bean’s classloader;
  14. Invoke the sixth callback interfaceBeanFactoryAware#setBeanFactory()!
    • Call timing:BeanClassLoaderAwareAfter that, it is used to set up the beanFactory!
  15. Invoke the seventh callback interfaceBeanPostProcessor#postProcessBeforeInitialization()methods
    • Call timing is the partAwareAfter, before initializing the method! Pass in the currently instantiated object and beanName, and modify it before initialization!
  16. Callback the eighth more important lifecycle initialization method, which can be oneInitializingBeanThe bean of the interface can also bea class configured in XML, or it can be added@PostConstructAnnotation method!
    • The internal logic of this method can be written by the user, and the call time is: call after the completion of the instantiation!
  17. Callback Ninth callback interfaceBeanPostProcessor#postProcessAfterInitialization()Methods!
    • This method is called after the initialization method is executed, which is also the last step after Bean instantiation, and an important step for SpringAop implementation!
  18. Register the destruction method so that it can be destroyed when the Spring container is destroyed!

The overall method flow sample diagram is as follows:

image-20200923004654968

4. Corresponding source code structure diagram

image-20200923011042937

【 Recommended reading 】

  • Take you out of the source hell, from the principle of MyBatis to Spring source code extension implementation
  • Do you know the Spring BeanFactoryPostProcessors is how to do?
  • To learn Spring source code, you must know the BeanDefinition principle!
  • This is how you end up asking hundreds of people questions about Spring transactions in an interview?
  • The @Configuration class is invisible in Spring
  • Angry! Interviewer you come over, I will give you a handwritten Spring Aop implementation!
  • Swastika word long, help you depth of Spring cycle rely on source code implementation!
  • I heard that you are confused when you read the Spring source code? I set up the shelves for you. You fill them out!

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