preface

It is normal to be asked about the Bean life cycle in the interview process. I believe many people can answer the question, but in the Spring framework, the difficulty is increased a lot. Today we will talk about the Bean declaration cycle in the Spring framework

First, the Bean’s life cycle

In terms of Bean life cycles, if we don’t talk about Spring, many people actually think of New, instantiating beans in the form of New objects, and when we don’t use beans anymore, At this point, our Java will perform garbage collection on the specified Bean.

But for Spring, the Bean life cycle can be a bit of a headache, because Spring is so complex and Bean management is very logical, with each layer having its own steps.

If we go to Baidu now and search for all the Spring Bean life cycles, many people will explain this

  • After the IoC container is started, the corresponding bean is not instantiated immediately, and the container only has the BeanDefinition of all objects (BeanDefinition: It is the container that relies on the XML configuration information loaded by some tool to parse and analyze and group the parsed information into the appropriate BeanDefinitions. It is only when getBean() is called that it is possible to trigger the Bean instantiation phase

Some things are less well explained, such as why it is possible to trigger Bean instantiation only when getBean() is called.

Life cycle flow chart

Simplified layout solution

In this diagram, the life cycle of a Bean in Spring is divided into several steps:

  1. Instantiate the Bean object through the constructor.
  2. Set the properties of an object through setter methods.
  3. Aware, its subclass BeanNameAware, passes the Bean’S ID(the ID registered in XML) by calling the Bean’s setBeanName() method, which is called when the Bean is initialized. This method is used to get the ID of the BeanFactory and Bean registered in the XML.
  4. If the Bean implements BeanFactoryAware, then the factory call to setBeanFactory(BeanFactory var1) passes in arguments of its own.
  5. The Bean instance is passed to the BeanPostProcessor postProcessBeforeInitialization in front.
  6. Complete the initialization of the Bean
  7. The Bean instance passed to rear the BeanPostProcessor postProcessAfterInitialization method.
  8. At this point, when the Bean is ready to take off, you’ll call the Destroy method from DisposableBean to DisposableBean at the last moment.

If the interviewer asks this question in an interview, and you start with the diagram and you give it all to him, then the answer, if you don’t have to dig a little deeper, might be enough.

And then there is the fundamental argument for what is written above.

And we sometimes have a hard time remembering these details, maybe we don’t understand them very well, but we can remember them in four or five ways,

  • Construction instantiation
  • Attribute assignment
  • Complete initialization
  • (Pre and post processing)
  • Destroy after use

By remembering these five aspects, you may be able to expand the picture and answer the interviewer’s questions in a concise way.

Code validation

package com.yld.bean; import org.springframework.beans.factory.BeanNameAware; public class Person implements BeanNameAware { private String name; /** * public void override ()setBeanName(String s) {         System.out.println("Call setName assignment in BeanNameAware");     }      public Person() {} /** * attribute assignment * @param name */ public voidsetName(String name) {         System.out.println("Set object property setName().."); this.name = name; } /** * Bean initialization */ public voidinitBeanPerson() {         System.out.println("Initialize Bean"); } /** * Bean method uses: speak */ public voidspeak() {         System.out.println("Use the Speak method of beans"); } /** * destroy Bean */ public voiddestroyBeanPerson() {         System.out.println("Destruction of Bean"); }}Copy the code

The Main method

public static void main(String[] args) {         ClassPathXmlApplicationContext pathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");         Person person = (Person)pathXmlApplicationContext.getBean("person");         person.speak();         pathXmlApplicationContext.close();     } Copy the code

Running Result Display

D: \ develop \ JDK8 \ jdk1.8.0 _181 \ bin \ Java exe"-javaagent:D:\develop\IDEA\IntelliJ IDEA 2018.1.8\lib\idea_rt.jar=63906:D:\develop\IDEA\IntelliJ IDEA 2018.1.8\bin"- Dfile. Encoding = utf-8 - classpath D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ charsets jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ deploy the jar. D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ access - bridge - 64. The jar. D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ cldrdata jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ DNSNS jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ jaccess jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ JFXRT jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ localedata jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ nashorn jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ sunec jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ sunjce_provider jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ sunmscapi jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ sunpkcs11 jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ ext \ zipfs jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ javaws jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ jce jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ JFR jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ JFXSWT jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ jsse jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ management - agent jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ plugin jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ resources jar; D: \ develop \ JDK8 \ jdk1.8.0 _181 \ jre \ lib \ rt jar; D:\develop\IDEAProject\KaiYuan\target\classes; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework/boot/spring - the boot - starter \ 2.1.8 RELEASE \ spring - the boot - starter - 2.1 .8.RELEASE.jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework/boot/spring - the boot \ 2.1.8 RELEASE \ spring - the boot - 2.1.8. The jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework \ spring - the context \ 5.1.9 RELEASE \ spring - the context - 5.1.9. The jar. C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework \ spring aop \ 5.1.9 - RELEASE \ spring aop -- 5.1.9. The jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework \ spring - beans \ 5.1.9 RELEASE \ spring - beans - 5.1.9. The jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework \ spring - expression \ 5.1.9 RELEASE \ spring - expression - 5.1.9. RELEAS E.jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework/boot/spring - the boot - autoconfigure \ 2.1.8 RELEASE \ spring - the boot - autoc Onfigure - 2.1.8. RELEASE. The jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework/boot/spring - the boot - starter - logging \ 2.1.8 RELEASE \ spring - the boot - sta Rter - logging - 2.1.8. RELEASE. The jar; C: \ Users \ \ Administrator \. M2 \ repository, ch, qos, logback \ \ 1.2.3 logback - classic \ logback - classic - 1.2.3. Jar; C: \ Users \ \ Administrator \. M2 \ repository, ch, qos, logback \ logback - core \ 1.2.3 \ logback - core - 1.2.3. Jar; C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4 j - to - slf4j \ 2.11.2 \log4 j - to - slf4j - 2.11.2. Jar; C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4 j - API \ 2.11.2 \log4 j - API - 2.11.2 jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ slf4j, jul - to - slf4j, 1.7.28, jul - to - slf4j - 1.7.28. Jar; C: \ Users \ \ Administrator \. M2 \ repository \ \ javax.mail javax.mail \ an annotation annotation - API \ 1.3.2 \ javax.mail annotation - API - 1.3.2. Jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework \ spring - the core \ 5.1.9 RELEASE \ spring - core - 5.1.9. The jar. C: \ Users \ \ Administrator \. M2 \ repository \ org \ springframework \ spring - the JCL \ 5.1.9 RELEASE \ spring - the JCL - 5.1.9. The jar. C: \ Users \ \ Administrator \. M2 \ repository \ org \ yaml \ snakeyaml \ \ snakeyaml 1.23-1.23. Jar; C: \ Users \ \ Administrator \. M2 \ repository \ org \ slf4j \ \ 1.7.28 \ slf4j slf4j - API - API - 1.7.28. Jar com. Yld. Bean. The Test 16:54:58. 817 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing Org. Springframework. Context. Support. ClassPathXmlApplicationContext @ 123772 c4 16:54:59 074 [main] the DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 1 bean definitions from class path resource [the applicationcontext.xml] 16:54:59. 121. [the main] the DEBUG org. Springframework. Beans. Factory. Support. DefaultListableBeanFactory - Creating shared instance of singleton bean'person'Setting Object PropertiessetName().. Call BeanNameAwaresetName assignment initializes the Bean using the Bean's Speak method 16:54:59.232 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@123772c4, Started on Sun Jun 07 16:54:58 CST 2020 Process finished withexit code 0 Copy the code

Is it as expected? After answering the interviewer with a case study, we’d better study the source code, after all, the research will be better understood, right?

InstantiationAwareBeanPostProcessor

This class inherits BeanPostProcessor and what does this class do? The source code comment looks like this:

Method one:

@Nullable default Object postProcessBeforeInstantiation(Class<? > beanClass, String beanName) throws BeansException {returnnull; } Apply the Bean handler before the target Bean is instantiated. The returned bean object may bea use of a proxy bean rather than a target,Copy the code

This means postProcessBeforeInstantiation in bean instantiation call before, if this is also our another face in the interview to pilot the use of AOP? When the interviewer asks you for an example, you can use the source code in Spring to explain it to him, and make the interviewer want to see if you have it.

Method 2: You can see that the method is inside the attribute assignment method, but before the actual assignment operation is performed. The return value is Boolean.

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {         return true;     } Copy the code

If the return value is false, then the assignment has failed and the assignment has been blocked indirectly.

The initialized class is the same as the BeanPostProcessor

Method one:

Before any Bean initialization callback such as after the initialization of the Bean attribute set @ Nullable default Object postProcessBeforeInitialization (Object Bean, String beanName) throws BeansException {return bean;     } Copy the code

Method 2:

Apply this Bean post-handler to a given new Bean instance, any Bean initialization callback (such as {@code} after initializing Bean properties or a custom init method). The bean is already populated with property values. The returned bean instance may be the original wrapper.

Apply this Bean post-handler to a given new Bean instance, any Bean initialization callback (such as {@code} after initializing Bean properties or a custom init method). The bean is already populated with property values. The returned bean instance may be the original wrapper. @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;     } Copy the code

Similarly, the meaning of annotation translation is also very clear, which is why bloggers like to download a plug-in to see annotations, after all, the source code of this thing if you see others understand and their own understanding, sometimes the gap is also very big.