Please do not ask the life cycle of a Spring Bean!

Spring Bean's life cycle is a hot issue Spring interview. This problem by examining the microscopic understanding of Spring, but also examine the macro understanding of Spring's not easy to want good answer! This article hopes to be able to start from the source point of view, to help the interviewer to get a thorough Spring Bean's life cycle.

Only four!

Yes, Spring Bean's life cycle is only four stages. These four stages and each stage corresponding extension point to blend together, although there is no problem, but this is very messy, difficult to remember. To completely clear Spring's life cycle, we must first keep in mind these four stages. Examples injection property assignment and construction of correspondence and setter methods, the user can initialize and destruction are two phases custom extension. Between these four steps interspersed with a variety of extension points, we will speak later.

  1. Instantiation Instantiation
  2. Populate property assignment
  3. Initialization Initialization
  4. Destruction Destruction

Instantiate -> property assignment -> Initialization -> destruction

The main logic in doCreate () method, the logic is clear, that is, call the following three methods in the order, these three methods-one correspondence with the three stages of the life cycle is very important, it will be involved in the subsequent expansion interface analysis.

  1. createBeanInstance () -> instantiate
  2. populateBean () -> property assignment
  3. initializeBean () -> initialization

Source code as follows, to prove instantiated, there is property assignment and initialization of the three life cycle. Spring source on this article will ignore the irrelevant part, easy to understand:

// 忽略了无关代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (instanceWrapper == null) {
       // 实例化阶段!
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
       // 属性赋值阶段!
      populateBean(beanName, mbd, instanceWrapper);
       // 初始化阶段!
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }

   
   }

As for destruction, it is called when the container is closed, seeConfigurableApplicationContext#close()

Common extension points

Common Spring lifecycle extension points is very large, so the problem is not do not know, but can not remember or mind is not strong. In fact, the root cause is not enough to know not remember, here to help you remember the source code + classification by the way.

The first category: Bean influence of multiple interfaces

Bean implements these interfaces will be cut into multiple Bean's life cycle. Because of this, these functional interface is very powerful, Spring internal expansion often use these interfaces, such as automatic injection and the achievement of AOP and they are related.

  • BeanPostProcessor
  • InstantiationAwareBeanPostProcessor

The two brothers could be extended in the Spring the most important two interfaces! InstantiationAwareBeanPostProcessor acting instantiated front stage, BeanPostProcessor acting initialization before and after the stage. It corresponds exactly to the first and third stages of the life cycle. To better understand through map:

4558491-dc3eebbd1d6c65f4.png
Unnamed file (1) .png

InstantiationAwareBeanPostProcessor actually inherited BeanPostProcessor interface, in the strict sense, they are not brothers, but two father and son. But we focus on the impact of specific examples stage of the life cycle from the perspective of the figure omitted inherited from BeanPostProcessor method.

InstantiationAwareBeanPostProcessor extends BeanPostProcessor
InstantiationAwareBeanPostProcessor source code analysis:
  • postProcessBeforeInstantiation call point, ignore independent code:
@Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            // postProcessBeforeInstantiation方法调用点,这里就不跟进了,
            // 有兴趣的同学可以自己看下,就是for循环调用所有的InstantiationAwareBeanPostProcessor
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        
        try {   
            // 上文提到的doCreateBean方法,可以看到
            // postProcessBeforeInstantiation方法在创建Bean之前调用
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        
    }

You can see, postProcessBeforeInstantiation called before doCreateBean, that is, before the bean instance of the call, the source comments in English explains the return value of this method will replace the original Bean as a proxy, which is the key point and other functions implemented Aop.

  • postProcessAfterInstantiation call point, ignore independent code:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   boolean continueWithPropertyPopulation = true;
    // InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
    // 方法作为属性赋值的前置检查条件,在属性赋值之前执行,能够影响是否进行属性赋值!
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }

   // 忽略后续的属性赋值操作代码
}

This method can be seen in the property assignment method, but before the actual execution assignment. Whose return value is boolean, property assignment can block the return phase to false ( continueWithPropertyPopulation = false;).

It calls on the timing analysis source implementation phase interspersed in BeanPostProcessor Aware Interface below, as part Aware function is implemented by him! Just remember BeanPostProcessor first call on it before or after initialization.

The second category: Only one call interface

This category is feature-rich interface features, commonly used in user-defined extensions.
In the second category can be divided into two categories:

  1. Aware types of interfaces
  2. Lifecycle interfaces
Aware omniscient

Aware of the role of the type of interface that allows us to get some resources Spring container. Basically be able to see the name to know Italy, before the name is Aware of what you can get resources such BeanNameAwarecan get BeanName, and so on. The time required to call Note: All Aware methods are called before the initialization phase!
Aware of many interfaces, here the same way by classification to help you remember.
Aware Interface concrete can be divided into two groups, as to why so many points, see below for source code analysis. Also the following order in the execution sequence Aware interface can see the name of the interface EENOW not explained.

Aware Group1

  1. BeanNameAware
  2. BeanClassLoaderAware
  3. BeanFactoryAware

Aware Group2

  1. EnvironmentAware
  2. EmbeddedValueResolverAware perhaps not many people know this, that implements this interface can obtain Spring EL resolver, the user's custom annotations need support when spel expression can use, very convenient.
  3. ApplicationContextAware (ResourceLoaderAware \ ApplicationEventPublisherAware \ MessageSourceAware) these interfaces may be a little ignorant, in fact, these interfaces can be credited with that return values ​​are essentially the current ApplicationContext object because ApplicationContext is a composite connectors, as follows:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}

Another difference involved here pavement questions, and ApplicationContext BeanFactory can start from ApplicationContext inherited these interfaces, two interfaces is removed ApplicationContext BeanFactory associated unique features, not described in detail herein.

Aware call timing source code analysis

Details are as follows, ignoring the part of the independent code. Code location is initializeBean details of the method we mentioned above, this also explains Aware is called before the initialization phase!

    // 见名知意,初始化阶段调用的方法
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

        // 这里调用的是Group1中的三个Bean开头的Aware
        invokeAwareMethods(beanName, bean);

        Object wrappedBean = bean;
        
        // 这里调用的是Group2中的几个Aware,
        // 而实质上这里就是前面所说的BeanPostProcessor的调用点!
        // 也就是说与Group1中的Aware不同,这里是通过BeanPostProcessor(ApplicationContextAwareProcessor)实现的。
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        // 下文即将介绍的InitializingBean调用点
        invokeInitMethods(beanName, wrappedBean, mbd);
        // BeanPostProcessor的另一个调用点
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

        return wrappedBean;
    }

Aware can see that not all use the same interface to invoke. Bean ×× Aware is called directly in the code, while the ApplicationContext related Aware is achieved through BeanPostProcessor # postProcessBeforeInitialization (). Interested can look at their own source ApplicationContextAwareProcessor this class, it is to determine whether Bean is currently being created to achieve the relevant Aware methods, if realized will call a callback method to transferring resources to the Bean.
As Spring Why do you realize, there should be no special considerations. Maybe and upgrade Spring concerned. Closed for modification based on the expansion of the principle of openness, Spring for some new Aware uses a scalable way to add.

BeanPostProcessor call timing can also be reflected here, surrounded invokeInitMethods method, it means that before and after the execution of the initialization phase.

Aware Interface on the implementation of the order, in fact, need only remember the first set before the second set of execution on the line. Each group calling sequence of each method Aware of fact, there is no need to remember, when the need arises point into the source code at a glance.

Two simple life cycle interfaces

As for the remaining two life cycle interface is very simple, and examples are the property assignment Spring helps us to do, be able to realize their own initialization and destruction of two life cycle stages.

  1. InitializingBean corresponds to the initialization phase of the lifecycle, the source of the above invokeInitMethods(beanName, wrappedBean, mbd);call method.
    One thing to note, because Aware methods are executed before the initialization method, so you can rest assured that bold use of resources Aware interface to obtain in the initialization process, which is the common way to extend Spring's our custom.
    In addition to achieving InitializingBean interfaces can also specify initialization method other than by way of annotation or xml configuration, as defined in several ways which call sequence in fact there is no need to remember. Because these methods are corresponding with a life cycle, but realized in different ways, we generally use only one of the ways.
  2. DisposableBean similar to the InitializingBean, corresponding to the destruction of life cycle stages, to ConfigurableApplicationContext # close () method as an inlet, is achieved by taking circulation Bean DisposableBean implements all interfaces and call its destroy () method. With self-interest can be at the source.

Further reading: BeanPostProcessor registered with the timing of the execution order

Registration timing

We know BeanPostProcessor also registered as Bean, then Spring is how to ensure that our business BeanPostProcessor before Bean initialization is complete it?
See our source familiar with the refresh () method, part of the independent code omitted:

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // 所有BeanPostProcesser初始化的调用点
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // 所有单例非懒加载Bean的调用点
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

    }

As can be seen, Spring is the first implementation of registerBeanPostProcessors () to register BeanPostProcessors, and then perform the initialization finishBeanFactoryInitialization our non-singleton lazy loading of Bean.

Execution order

BeanPostProcessor there are many, and each BeanPostProcessor affect multiple Bean, whose execution order is essential and must be able to control the execution order job. It should be on the order of execution ordering the introduction of two related interfaces: PriorityOrdered, Ordered

  • PriorityOrdered a first-class citizen, it is executed first, the return value between PriorityOrdered citizens sort through the interface

  • Ordered second-class citizens, and then execute, return values ​​between Ordered citizens sort through the interface

  • Have not achieved a third-class citizens, the last execution

In the following source code, you can clearly see the logical register Spring BeanPostProcessor types of implement are grouped according to different sorting interfaces. To join a high-priority, low priority after joining.

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先,加入实现了PriorityOrdered接口的BeanPostProcessors,顺便根据PriorityOrdered排了序
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 然后,加入实现了Ordered接口的BeanPostProcessors,顺便根据Ordered排了序
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后加入其他常规的BeanPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

Values ​​are sorted according to the sorting interfaces return default ascending sort, the return value is lower the higher the priority.

    /**
     * Useful constant for the highest precedence value.
     * @see java.lang.Integer#MIN_VALUE
     */
    int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

    /**
     * Useful constant for the lowest precedence value.
     * @see java.lang.Integer#MAX_VALUE
     */
    int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

PriorityOrdered, Ordered interface as the entire Spring Framework common sort interfaces, widely used in the Spring, the interface is also very important.

to sum up

Spring Bean's life cycle into 四个阶段and 多个扩展点. Extension points can be divided into 影响多个Beanand 影响单个Bean. Are summarized as follows:
four stages

  • Instantiation Instantiation
  • Populate property assignment
  • Initialization Initialization
  • Destruction Destruction

More extension points

  • Affect multiple Bean
    • BeanPostProcessor
    • InstantiationAwareBeanPostProcessor
  • Affects a single Bean
    • Aware
      • Aware Group1
        • BeanNameAware
        • BeanClassLoaderAware
        • BeanFactoryAware
      • Aware Group2
        • EnvironmentAware
        • EmbeddedValueResolverAware
        • ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)
    • The life cycle
      • InitializingBean
      • DisposableBean

So far, Spring Bean life cycle of introduction, because the author is limited it is inevitable omissions, welcome message error correction.

Reproduced in: https: //www.jianshu.com/p/1dec08d290c1

Guess you like

Origin blog.csdn.net/weixin_34026484/article/details/91173946