好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

SpringBoot源码之Bean的生命周期

入口方法为SpringApplication#run()

1. SpringApplication#run()

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

/**

      * Run the Spring application, creating and refreshing a new

      * {@link ApplicationContext}.

      * @param args the application arguments (usually passed from a Java main method)

      * @return a running {@link ApplicationContext}

      */

     public ConfigurableApplicationContext run(String... args) {

         long startTime = System.nanoTime();

         DefaultBootstrapContext bootstrapContext = createBootstrapContext();

         ConfigurableApplicationContext context = null ;

         configureHeadlessProperty();

         SpringApplicationRunListeners listeners = getRunListeners(args);

         listeners.starting(bootstrapContext, this .mainApplicationClass);

         try {

             ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

             ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);

             Banner printedBanner = printBanner(environment);

             context = createApplicationContext();

             context.setApplicationStartup( this .applicationStartup);

             prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);

             refreshContext(context);

             afterRefresh(context, applicationArguments);

             Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);

             if ( this .logStartupInfo) {

                 new StartupInfoLogger( this .mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);

             }

             listeners.started(context, timeTakenToStartup);

             callRunners(context, applicationArguments);

         }

         catch (Throwable ex) {

             if (ex instanceof AbandonedRunException) {

                 throw ex;

             }

             handleRunFailure(context, ex, listeners);

             throw new IllegalStateException(ex);

         }

         try {

             if (context.isRunning()) {

                 Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);

                 listeners.ready(context, timeTakenToReady);

             }

         }

         catch (Throwable ex) {

             if (ex instanceof AbandonedRunException) {

                 throw ex;

             }

             handleRunFailure(context, ex, null );

             throw new IllegalStateException(ex);

         }

         return context;

     }

2. SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

@Override

     public void refresh() throws BeansException, IllegalStateException {

         synchronized ( this .startupShutdownMonitor) {

             StartupStep contextRefresh = this .applicationStartup.start( "spring.context.refresh" );

 

             // Prepare this context for refreshing.

             prepareRefresh();

 

             // Tell the subclass to refresh the internal bean factory.

             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

 

             // Prepare the bean factory for use in this context.

             prepareBeanFactory(beanFactory);

 

             try {

                 // Allows post-processing of the bean factory in context subclasses.

                 postProcessBeanFactory(beanFactory);

 

                 StartupStep beanPostProcess = this .applicationStartup.start( "spring.context.beans.post-process" );

                 // Invoke factory processors registered as beans in the context.

                 invokeBeanFactoryPostProcessors(beanFactory);

 

                 // Register bean processors that intercept bean creation.

                 registerBeanPostProcessors(beanFactory);

                 beanPostProcess.end();

 

                 // 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.

                 finishBeanFactoryInitialization(beanFactory);

 

                 // Last step: publish corresponding event.

                 finishRefresh();

             }

 

             catch (BeansException ex) {

                 if (logger.isWarnEnabled()) {

                     logger.warn( "Exception encountered during context initialization - " +

                             "cancelling refresh attempt: " + ex);

                 }

 

                 // Destroy already created singletons to avoid dangling resources.

                 destroyBeans();

 

                 // Reset 'active' flag.

                 cancelRefresh(ex);

 

                 // Propagate exception to caller.

                 throw ex;

             }

 

             finally {

                 // Reset common introspection caches in Spring's core, since we

                 // might not ever need metadata for singleton beans anymore...

                 resetCommonCaches();

                 contextRefresh.end();

             }

         }

     }

3. SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

@Override

     public void preInstantiateSingletons() throws BeansException {

         if (logger.isTraceEnabled()) {

             logger.trace( "Pre-instantiating singletons in " + this );

         }

 

         // Iterate over a copy to allow for init methods which in turn register new bean definitions.

         // While this may not be part of the regular factory bootstrap, it does otherwise work fine.

         List<String> beanNames = new ArrayList<>( this .beanDefinitionNames);

 

         // Trigger initialization of all non-lazy singleton beans...

         for (String beanName : beanNames) {

             RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

             if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

                 if (isFactoryBean(beanName)) {

                     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);

                     if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {

                         getBean(beanName);

                     }

                 }

                 else {

                     // 此处就是初始化bean的方法

                     getBean(beanName);

                 }

             }

         }

 

         // Trigger post-initialization callback for all applicable beans...

         for (String beanName : beanNames) {

             // 此处就是解决循环依赖的代码

             Object singletonInstance = getSingleton(beanName);

             if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {

                 StartupStep smartInitialize = this .getApplicationStartup().start( "spring.beans.smart-initialize" )

                         .tag( "beanName" , beanName);

                 smartSingleton.afterSingletonsInstantiated();

                 smartInitialize.end();

             }

         }

     }

解决循环依赖的代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

protected Object getSingleton(String beanName, boolean allowEarlyReference) {

// 尝试从缓存中获取成品的目标对象,如果存在,则直接返回

   Object singletonObject = this .singletonObjects.get(beanName);

   // 如果缓存中不存在目标对象,则判断当前对象是否已经处于创建过程中,在前面的讲解中,第一次尝试获取A对象

   // 的实例之后,就会将A对象标记为正在创建中,因而最后再尝试获取A对象的时候,这里的if判断就会为true

   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {

     synchronized ( this .singletonObjects) {

       singletonObject = this .earlySingletonObjects.get(beanName);

       if (singletonObject == null && allowEarlyReference) {

         // 这里的singletonFactories是一个Map,其key是bean的名称,而值是一个ObjectFactory类型的

         // 对象,这里对于A和B而言,调用图其getObject()方法返回的就是A和B对象的实例,无论是否是半成品

         ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName);

         if (singletonFactory != null ) {

           // 获取目标对象的实例

           singletonObject = singletonFactory.getObject();

           this .earlySingletonObjects.put(beanName, singletonObject);

           this .singletonFactories.remove(beanName);

         }

       }

     }

   }

   return singletonObject;

}

一级缓存,singletonObjects 单例缓存,存储已经实例化的单例bean。 二级缓存,earlySingletonObjects 提前暴露的单例缓存,这里存储的bean是刚刚构造完成,但还会通过属性注入bean。 三级缓存,singletonFactories 生产单例的工厂缓存,存储工厂。

解决原理如下:

在第一层中,先去获取 A 的 Bean,发现没有就准备去创建一个,然后将 A 的代理工厂放入[三级缓存](这个 A 其实是一个半成品,还没有对里面的属性进行注入),但是 A 依赖 B 的创建,就必须先去创建 B; 在第二层中,准备创建 B,发现 B 又依赖 A,需要先去创建 A,去创建 A,因为第一层已经创建了 A 的代理工厂,直接从[三级缓存]中拿到 A 的代理工厂,获取 A 的代理对象,放入[二级缓存],并清除[三级缓存]; 有了 A 的代理对象,对 A 的依赖完美解决(这里的 A 仍然是个半成品),B 初始化成功。在 B 初始化成功,完成 A 对象的属性注入,然后再填充 A 的其它属性,以及 A 的其它步骤(包括 AOP),完成对 A 完整的初始化功能(这里的 A 才是完整的 Bean)。 将 A 放入[一级缓存]。

 

4. SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()=>AbstractBeanFactory#getBean() => AbstractBeanFactory#doGetBean()=>AbstractBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#doCreateBean()

bean的生命周期:

1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation
跟进doCreateBean()

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

@Override

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 

       throws BeanCreationException { 

  

    if (logger.isTraceEnabled()) { 

       logger.trace( "Creating instance of bean '" + beanName + "'" ); 

    } 

    RootBeanDefinition mbdToUse = mbd; 

  

    // Make sure bean class is actually resolved at this point, and 

    // clone the bean definition in case of a dynamically resolved Class   // which cannot be stored in the shared merged bean definition.   Class<?> resolvedClass = resolveBeanClass(mbd, beanName); 

    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null ) { 

       mbdToUse = new RootBeanDefinition(mbd); 

       mbdToUse.setBeanClass(resolvedClass); 

    } 

  

    // Prepare method overrides. 

    try { 

       mbdToUse.prepareMethodOverrides(); 

    } 

    catch (BeanDefinitionValidationException ex) { 

       throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), 

             beanName, "Validation of method overrides failed" , ex); 

    } 

  

    try { 

       // 1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation

       Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 

       if (bean != null ) { 

          return bean; 

       } 

    } 

    catch (Throwable ex) { 

       throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 

             "BeanPostProcessor before instantiation of bean failed" , ex); 

    } 

  

    try { 

       // 跟进doCreateBean()

       Object beanInstance = doCreateBean(beanName, mbdToUse, args); 

       if (logger.isTraceEnabled()) { 

          logger.trace( "Finished creating instance of bean '" + beanName + "'" ); 

       } 

       return beanInstance; 

    } 

    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { 

       // A previously detected exception with proper bean creation context already, 

       // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.      throw ex; 

    } 

    catch (Throwable ex) { 

       throw new BeanCreationException( 

             mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation" , ex); 

    } 

}

2.创建bean实例

跟进populateBean()
跟进initializeBean()

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 

       throws BeanCreationException { 

  

    // Instantiate the bean. 

    BeanWrapper instanceWrapper = null ; 

    if (mbd.isSingleton()) { 

       instanceWrapper = this .factoryBeanInstanceCache.remove(beanName); 

    } 

    if (instanceWrapper == null ) {

       // 2.创建bean实例

       instanceWrapper = createBeanInstance(beanName, mbd, args); 

    } 

    Object bean = instanceWrapper.getWrappedInstance(); 

    Class<?> beanType = instanceWrapper.getWrappedClass(); 

    if (beanType != NullBean. class ) { 

       mbd.resolvedTargetType = beanType; 

    } 

  

    // Allow post-processors to modify the merged bean definition. 

    synchronized (mbd.postProcessingLock) { 

       if (!mbd.postProcessed) { 

          try {

             applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 

          } 

          catch (Throwable ex) { 

             throw new BeanCreationException(mbd.getResourceDescription(), beanName, 

                   "Post-processing of merged bean definition failed" , ex); 

          } 

          mbd.markAsPostProcessed(); 

       } 

    } 

  

    // Eagerly cache singletons to be able to resolve circular references 

    // even when triggered by lifecycle interfaces like BeanFactoryAware.   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 

          isSingletonCurrentlyInCreation(beanName)); 

    if (earlySingletonExposure) { 

       if (logger.isTraceEnabled()) { 

          logger.trace( "Eagerly caching bean '" + beanName + 

                "' to allow for resolving potential circular references" ); 

       } 

       addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 

    } 

  

    // Initialize the bean instance. 

    Object exposedObject = bean; 

    try {

       // 跟进populateBean()

       populateBean(beanName, mbd, instanceWrapper);

       // 跟进initializeBean()

       exposedObject = initializeBean(beanName, exposedObject, mbd); 

    } 

    catch (Throwable ex) { 

       if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) { 

          throw bce; 

       } 

       else { 

          throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex); 

       } 

    } 

  

    if (earlySingletonExposure) { 

       Object earlySingletonReference = getSingleton(beanName, false ); 

       if (earlySingletonReference != null ) { 

          if (exposedObject == bean) { 

             exposedObject = earlySingletonReference; 

          } 

          else if (! this .allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { 

             String[] dependentBeans = getDependentBeans(beanName); 

             Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); 

             for (String dependentBean : dependentBeans) { 

                if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { 

                   actualDependentBeans.add(dependentBean); 

                } 

             } 

             if (!actualDependentBeans.isEmpty()) { 

                throw new BeanCurrentlyInCreationException(beanName, 

                      "Bean with name '" + beanName + "' has been injected into other beans [" + 

                      StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + 

                      "] in its raw version as part of a circular reference, but has eventually been " + 

                      "wrapped. This means that said other beans do not use the final version of the " + 

                      "bean. This is often the result of over-eager type matching - consider using " + 

                      "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example." ); 

             } 

          } 

       } 

    } 

  

    // Register bean as disposable. 

    try { 

       registerDisposableBeanIfNecessary(beanName, bean, mbd); 

    } 

    catch (BeanDefinitionValidationException ex) { 

       throw new BeanCreationException( 

             mbd.getResourceDescription(), beanName, "Invalid destruction signature" , ex); 

    } 

  

    return exposedObject; 

}

3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation

4.注入bean属性

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { 

    if (bw == null ) { 

       if (mbd.hasPropertyValues()) { 

          throw new BeanCreationException( 

                mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance" ); 

       } 

       else { 

          // Skip property population phase for null instance. 

          return ; 

       } 

    } 

  

    if (bw.getWrappedClass().isRecord()) { 

       if (mbd.hasPropertyValues()) { 

          throw new BeanCreationException( 

                mbd.getResourceDescription(), beanName, "Cannot apply property values to a record" ); 

       } 

       else { 

          // Skip property population phase for records since they are immutable. 

          return ; 

       } 

    } 

  

       // 3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation

       for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { 

          if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { 

             return ; 

          } 

       } 

    } 

  

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null ); 

  

    int resolvedAutowireMode = mbd.getResolvedAutowireMode(); 

    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { 

       MutablePropertyValues newPvs = new MutablePropertyValues(pvs); 

       // Add property values based on autowire by name if applicable. 

       if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { 

          autowireByName(beanName, mbd, bw, newPvs); 

       } 

       // Add property values based on autowire by type if applicable. 

       if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { 

          autowireByType(beanName, mbd, bw, newPvs); 

       } 

       pvs = newPvs; 

    } 

    if (hasInstantiationAwareBeanPostProcessors()) { 

       if (pvs == null ) {

          pvs = mbd.getPropertyValues(); 

       } 

       for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { 

          PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); 

          if (pvsToUse == null ) { 

             return ; 

          } 

          pvs = pvsToUse; 

       } 

    } 

  

    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); 

    if (needsDepCheck) { 

       PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); 

       checkDependencies(beanName, mbd, filteredPds, pvs); 

    } 

  

    if (pvs != null ) {

       // 4.注入属性 

       applyPropertyValues(beanName, mbd, bw, pvs); 

    } 

}

5.设置Aware接口的属性

6.调用BeanPostProcessor的初始化前置方法

7.先((InitializingBean) bean).afterPropertiesSet(),后调用init-method方法,进行初始化操作

8.调用BeanPostProcessor的初始化后置方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

     // 5.设置Aware接口的属性

    invokeAwareMethods(beanName, bean); 

  

    Object wrappedBean = bean; 

    if (mbd == null || !mbd.isSynthetic()) {

       // 5.调用BeanPostProcessor的初始化前置方法 

       wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 

    } 

  

    try {

       // 6.调用init-method方法,进行初始化操作 

       invokeInitMethods(beanName, wrappedBean, mbd); 

    } 

    catch (Throwable ex) { 

       throw new BeanCreationException( 

             (mbd != null ? mbd.getResourceDescription() : null ), beanName, ex.getMessage(), ex); 

    } 

    if (mbd == null || !mbd.isSynthetic()) {

       // 7. 调用BeanPostProcessor的初始化后置方法

       wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 

    } 

  

    return wrappedBean; 

}

以上就是SpringBoot源码之Bean的生命周期的详细内容,更多关于SpringBoot Bean生命周期的资料请关注其它相关文章!

原文链接:https://blog.csdn.net/qq_35688140/article/details/130117398

查看更多关于SpringBoot源码之Bean的生命周期的详细内容...

  阅读:17次