The login
registered
Write an article
Home page
Download the APP

Interviewer: Can you describe the life cycle of Spring beans?

Java fe

Interviewer: Can you describe the life cycle of Spring beans?

Write first (recommended reading) :

1. One SpringBoot problem? JAVA + concurrency +Spring+MySQL+ distributed +Redis+ algorithm +JVM, etc. It was all due to “Redis” that I almost got caught on three sides of Meituan. What a “false alarm”! 4. PDD failed miserably in three aspects: Java middleware, database and Spring framework.

1. The introduction

“Can you describe the life cycle of Spring beans?” Spring Spring Spring Spring Spring Spring Spring Spring Spring

When I was preparing for the interview, I searched online for answers, and most of them were based on the process shown in the picture below.


image.png

But when I first saw it, I had a lot of trouble, “Aware, BeanPostProcessor…… What are all these? And there are so many steps. How do you memorize them?” .

In order to remember this process, we need to understand it first. In this article, we will help understand the Bean life cycle from the following two aspects:

  1. Lifecycle overview flow: The lifecycle of the Bean is summarized and understood in code;

  2. The role of extension points: Details the role of extension points involved in the Bean life cycle.

2. Outline lifecycle processes

The Bean life cycle can be summarized as four phases:

  1. Instantiation
  2. Attribute assignment (Populate)
  3. Initialization
  4. To destroy


image.png

  1. Instantiate: Step 1, instantiate a bean object;

  2. Property assignment: Step 2, set the bean’s properties and dependencies;

  3. Initialization: There are many steps from Step 3 to step 7. Step 5 and Step 6 are initialization operations, step 3 and Step 4 are performed before initialization, and Step 7 is performed after initialization.

  4. Destroy: Steps 8-10, 8 is not really destroy (it is not used yet), but register the call interface related to destroy before using it, in order to execute the corresponding method when steps 9 and 10 actually destroy the bean.

The doCreateBean() method executes each of the four phases in sequence:

// AbstractAutowireCapableBeanFactory.java protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 1\. InstanceWrapper = null; if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object exposedObject = bean; Try {// 2\. Assign the property populateBean(beanName, MBD, instanceWrapper); // 3\. Initialize exposedObject = initializeBean(beanName, exposedObject, MBD); } / / 4 \. Destruction - register callback interface try {registerDisposableBeanIfNecessary (beanName, bean, MBD); } return exposedObject; }Copy the code

Since initialization involves steps 3 to 7, it is quite complicated, so let’s step into the initializeBean() method to see the process in detail (the serial number of the annotation corresponds to the serial number in the figure) :

// AbstractAutowireCapableBeanFactory.java protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // 3\. Check the Aware related interface and set depends on the if (System. GetSecurityManager ()! = null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } // 4\. BeanPostProcessor Object wrappedBean = bean; if (mbd == null || ! mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } // 5\. To implement the InitializingBean interface, call the afterPropertiesSet() method // 6\. If a custom init-method method is configured, then try {invokeInitMethods(beanName, wrappedBean, MBD); } catch (Throwable ex) { throw new BeanCreationException( (mbd ! = null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } / / 7 \. BeanPostProceesor rear handle the if (MBD = = null | |! mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }Copy the code

In the invokInitMethods() method, the InitializingBean interface and init-method methods are checked, and the destruction process is similar:

// DisposableBeanAdapter.java public void destroy() { // 9\. If implement DisposableBean interfaces, the execution destory the if () method (enclosing invokeDisposableBean) {try {the if (System. GetSecurityManager ()! = null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean) this.bean).destroy(); }}} // 10\. To configure the custom detory-method method, execute if (this.destroyMethod! = null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName ! = null) { Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); if (methodToInvoke ! = null) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); }}}Copy the code

From the source code of Spring, we can intuitively see the execution process, and we can remember the process from these four stages: instantiation, attribute assignment, initialization, and destruction. Among them, initialization is more detailed, involving the concepts of Aware, BeanPostProcessor, InitializingBean and init-method. These are extension points that Spring provides, and their role is covered in the next section.

3. Function of extension points

3.1 Aware interface

If Spring detects that the bean implements the Aware interface, it will inject the appropriate dependencies into it. So by having the bean implement the Aware interface, you can get the corresponding Spring container resources in the bean.

The Aware interfaces provided in Spring are:

  1. BeanNameAware: Inject the current bean corresponding to beanName;
  2. BeanClassLoaderAware: inject the ClassLoader that loads the current bean;
  3. BeanFactoryAware: Inject a reference to the current BeanFactory container.

Its code implementation is as follows:

// AbstractAutowireCapableBeanFactory.java private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); }}}Copy the code

The Aware interface is also provided for containers of type BeanFactory, and for containers of type ApplicationContext, the Aware interface is injected via BeanPostProcessor. But its role is still to inject dependencies.

  1. EnvironmentAware: infuse Enviroment, generally used to obtain configuration properties;
  2. EmbeddedValueResolverAware: injection EmbeddedValueResolver (Spring EL parser), commonly used in parameter parsing;
  3. ApplicationContextAware (ResourceLoader ApplicationEventPublisherAware MessageSourceAware) : injection ApplicationContext container itself.

Its code implementation is as follows:

// ApplicationContextAwareProcessor.java private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware)bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext); }}Copy the code

3.2 BeanPostProcessor

BeanPostProcessor is a powerful Spring extension point for modifying beans that works on all beans in the container and is defined as follows:

Public interface BeanPostProcessor {/ / initializes the pre-processing default Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { return bean; } / / rear initialization processing default Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { return bean; }}Copy the code

Common scenarios are as follows:

  1. For the implementation class that marks the interface, customize the processing. ApplicationContextAwareProcessor section 3.1 say, for example, for them into corresponding rely on; For another example, a custom class that implements a decryption interface will decrypt its attributes.
  2. Provides a proxy implementation for the current object. The Spring AOP feature, for example, generates a proxy class for an object and then returns it.
// AbstractAutoProxyCreator.java public Object postProcessBeforeInstantiation(Class<? > beanClass, String beanName) { TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource ! = null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); // return proxy class return proxy; } return null; }Copy the code

3.3 InitializingBean and init – method

Initializingbeans and init-Method are extension points Spring provides for bean initialization.

The InitializingBean interface is defined as follows:

public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}
Copy the code

Write the initialization logic in the afterPropertiesSet() method.

Specify init-method, specify the initialization method:

<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="demo" class="com.chaycao.Demo" init-method="init()"/> </beans>Copy the code

DisposableBean and Destory-Method are similar to the above and will not be described.

4. To summarize

To summarize how to remember the life cycle of Spring beans:

  • The first stage is instantiation, attribute assignment, initialization and destruction.

  • The specific operations of initialization include dependency injection of Aware interface, BeanPostProcessor processing before and after initialization, InitializingBean initialization and init-method initialization.

  • For specific destruction operations, you can register the relevant destruction callback interface, and finally DisposableBean and destory-method.

Author: Grass Pinch son original link: juejin.cn/post/684490…

Recommended readingMore highlights

  • In Spring, the objects that make up the body of an application and are managed by the Spring IOC container are called beans… Mr. Java_ So read 77 Comments 1 likes 0
  • Spring does not start the Bean instantiation process as soon as the container is started. Mr. Java_ So Read 672 Comments 0 likes 3
  • Spring Bean Lifecycle (IoC)… Bean buns are not fish
  • We’ll start with the difference between BeanFacory and ApplicationContext. They can all create IOC containers, but there are areas… Landlord’s little Hei Hei Read 41 comments 0 likes 1
  • As a member of the code farmers, I need to learn constantly. I will write some analysis summary and study notes on the blog to communicate with you after work. I also hope to use this kind of… Read 729 Comments 1 Upvote 51