preface
When you’re ready to review the life cycle of beans in Spring, and you start looking online, there’s a good chance you’ll see something like this:
Regardless of whether this map is comprehensive or not, but say this map, do you memorize and forget, forget and back?
Is it because you don’t understand why these steps are needed or why you need to do them in this order
After reading the complete IOC and AOP source code, I hope to talk about my Spring Bean life cycle through this article, to help you understand the memory of the whole process, rather than rote memorization!
Basic knowledge supplement
So-called understanding is also built on the basis of certain knowledge reserves, so here to supplement a few basic concepts first
The three phases of Bean creation
Spring creates a Bean in three steps
- Instantiate, you can think of it as new an object
- Property injection, which can be interpreted as calling setter methods to complete property injection
- Initialization, you can configure some of the initialization methods according to Spring rules (for example,
@PostConstruct
Annotations)
The concept of life cycle
The Bean life cycle refers to the process interspersed between the preceding three steps by the post-processor BeanPostprocessor
Analysis of the rear processor
Categorize by implementation interface
- Directly implemented
BeanPostProcessor
interface
The simplest post-processor, which directly implements the BeanPostProcessor interface, can only be executed before and after initialization
public interface BeanPostProcessor {
// The method executed before initialization
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean; } // The method executed after initialization default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } Copy the code
- Directly implemented
InstantiationAwareBeanPostProcessor
interface
A layer of extensions to the first post-processing can be performed before and after the Bean’s instantiation phase
// Inherits BeanPostProcessor, which provides two additional methods for execution in the phases before and after instantiation
The interface also provides a property injection method, since instantiation is immediately followed by property injection
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
// execute before instantiation
default Object postProcessBeforeInstantiation(Class
beanClass, String beanName) throws BeansException { return null; } // instantiate after default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } // Attribute injection default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } } Copy the code
- A dedicated post-processor inside Spring
Some people think that the third type of post-processor must be used to execute before and after the property injection. All I can say is, dude, that’s naive. Look at the picture below
In this case, isn’t it a bit redundant to provide two methods for the property injection phase? The third post-processor is actually designed specifically by Spring for its own use
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
// Guess the type of the bean, for example in the property injection phase we need to know which beans match the dependent type
@Nullable
defaultClass<? > predictBeanType(Class<? > beanClass, String beanName)throws BeansException {
return null; } We need to specify which constructor to use when instantiating the object @Nullable defaultConstructor<? >[] determineCandidateConstructors(Class<? > beanClass, String beanName) throws BeansException { return null; } // Get a pre-exposed object to resolve loop dependencies default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; } } Copy the code
We usually don’t think about this kind of post-processor execution when we’re exploring the life cycle
Details about the life cycle
With the above concepts in mind, let’s take a look at this diagram
At least now this diagram is missing the execution flow of the post-instantiation processor before and after instantiation, right?
Add on this, we take a look at, properties after injection and then is the initialization stage, before the start of the initialization phase should call BeanPostProcessor initialization method (postProcessBeforeInitialization), Then calls a custom initialization method, and finally call postProcessAfterInitialization, this is no problem, but why even before the initial call Aware interface method, may say, if you see the source code source code is written, so others is so of the design, But why design it this way? When we look at the source code at a certain stage, we should not only stop at the “what” stage, but also think about the “why”, which will help you understand the framework better
So why should the Aware interface be executed before initialization?
This is done because initialization may depend on the state provided by the Aware interface, as in the following example
@Component
public class A implements InitializingBean.ApplicationContextAware {
ApplicationContext applicationContext;
@Override public void afterPropertiesSet(a) throws Exception { // The initialization method uses the ApplicationContext provided by ApplicationContextAware System.out.println(applicationContext); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } } Copy the code
In this case, the Aware interface must be executed before initialization.
In addition, when discussing Bean initialization often encounter the following problems, @ PostConstruct, afterPropertiesSet init – method with XML configuration method of execution order.
Please note that @ PostConstruct actually postProcessBeforeInitialization methods in the treatment of, strictly speaking, it does not belong to the method called initialization phase, so this method is the first to call
Next, is it more expensive to call the afterPropertiesSet method or to perform the initialization method named in the configuration file? Let’s do this in pseudocode
// afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet()
// reflection calls init-method
// Step 1: Find the method
Method method = class.getMethod(methodName) // Step 2: reflection calls this methodmethod.invoke(bean.null) Copy the code
By comparison, the first method is definitely more efficient than the second one, where one only makes one method call and the other calls two reflections.
Therefore, afterPropertiesSet takes precedence over XML configuration
Therefore, the execution sequence of these three methods is:
@PostConstruct
Annotation annotation method- To achieve the
InitializingBean
Interface after the copyafterPropertiesSet
methods - Custom initialization methods in XML
At the completion of initialization, there is nothing to say, the final call postProcessAfterInitialization, whole Bean lifecycle to the end
conclusion
The main purpose of this article is to help you better understand the entire Bean life cycle, but understanding is based on a certain amount of knowledge stored
You should have at least a general understanding of Bean postprocessor and Bean creation, so you can sort out some of the details in this article
For example, why is the Aware interface executed before the initialization phase? Why do the three initialization methods press
@postconstruct, afterPropertiesSet, the initialization methods defined in XML are executed in this order.
This article will be my last article on IOC and AOP in the whole Spring. After this, I plan to do a Spring transaction topic, which is expected to be 6 to 7 articles. After the transaction, the study of the whole Spring source code will be over! It was supposed to take a year to finish, but since I recently left my job, I plan to finish the series full-time at home!
If this article helped you, give it a thumbs up! Also welcome to pay attention to my public number, wechat search: Programmer DMZ, or scan the two-dimensional code below, follow me to learn Java seriously, do a solid coder.
My name is DMZ, a small rookie crawling on the learning road!
This article is formatted using MDNICE