Spring Bean的生命週期(生命週期階段和擴展點分開)

Spring 有一些常用擴展點,瞭解Spring Bean的生命週期,能夠對spring宏觀有一定的認識,這裏嘗試答一下。

Spring Bean的生命週期分爲四個階段。這裏將spring Bean的四個階段添加部分常用擴展點便於理解。

一、spring bean 四個階段

1、實例化 instantiation(createBeanInstance)
2、屬性賦值 Populate (populateBean)
3、初始化 Initialization(initializeBean)
4、銷燬 Destruction(ConfigurableApplicationContext#close())

這個四個方法都放在AbstractAutowireCapableBeanFactory 中的doCreateBean的方法中,

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }
		//實例化
        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }
	.......................
        try {
        	//屬性賦值
            this.populateBean(beanName, mbd, instanceWrapper);
            //初始化
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

   ...........
    }

二、spring bean中的兩個重要接口

在這裏插入圖片描述
在四個過程中又Spring擴展中有兩個很重要的接口,InstantiationAwareBeanPostProcessor和BeanPostProcessor。這兩個接口實際是繼承關係,但由於這兩個接口在spring bean生命週期中的不同階段是 不同接口本身的方法起作用所以這裏將兩個接口分開來看。

InstantiationAwareBeanPostProcessor 與BeanPostProcessor 之間的關係

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
....
}

1、InstantiationAwareBeanPostProcessor 接口

(1)InstantiationAwareBeanPostProcessor 中的applyBeanPostProcessorsBeforeInstantiation 的接口
InstantiationAwareBeanPostProcessor調用地方依然在AbstractAutowireCapableBeanFactory 這類中 createBean方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
     ......

        Object beanInstance;
        try {
        
        //InstantiationAwareBeanPostProcessor 中的postProcessBeforeInstantiation方法
        
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var10) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
        }

        try {
        
        //spring bean 1、實例化 、屬性賦值、初始化 方法
        
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Finished creating instance of bean '" + beanName + "'");
            }

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            throw var7;
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
        }
    }

InstantiationAwareBeanPostProcessor 中的resolveBeforeInstantiation

 @Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = this.determineTargetType(beanName, mbd);
                if (targetType != null) {
                
                //在此方法中調用InstantiationAwareBeanPostProcessor 中postProcessBeforeInstantiation
                
                    bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        bean = this.applyBeanPostProccessorsAfterInitialization(bean, beanName);
                    }
                }
            }

            mbd.beforeInstantiationResolved = bean != null;
        }

        return bean;
    }

InstantiationAwareBeanPostProcessor 中的applyBeanPostProcessorsBeforeInstantiation

 @Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        Iterator var3 = this.getBeanPostProcessors().iterator();

        while(var3.hasNext()) {
            BeanPostProcessor bp = (BeanPostProcessor)var3.next();
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
            
            //當判斷接口中有有InstantiationAwareBeanPostProcessor則調用postProcessBeforeInstantiation
            
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

(2)InstantiationAwareBeanPostProcessor 中的postProcessAfterInstantiation,postProcessProperties的接口

InstantiationAwareBeanPostProcessor中的postProcessAfterInstantiation,postProcessProperties在AbstractAutowireCapableBeanFactory 這類中 createBean->populateBean 的接口中

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

                while(var5.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var5.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        
                        //InstantiationAwareBeanPostProcessor 中調用postProcessAfterInstantiation方法
                        
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }

            if (continueWithPropertyPopulation) {
                PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
                if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
                    MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                    if (mbd.getResolvedAutowireMode() == 1) {
                        this.autowireByName(beanName, mbd, bw, newPvs);
                    }

                    if (mbd.getResolvedAutowireMode() == 2) {
                        this.autowireByType(beanName, mbd, bw, newPvs);
                    }

                    pvs = newPvs;
                }

                boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
                boolean needsDepCheck = mbd.getDependencyCheck() != 0;
                PropertyDescriptor[] filteredPds = null;
                if (hasInstAwareBpps) {
                    if (pvs == null) {
                        pvs = mbd.getPropertyValues();
                    }

                    Iterator var9 = this.getBeanPostProcessors().iterator();

                    while(var9.hasNext()) {
                        BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                            
                            //InstantiationAwareBeanPostProcessor  調用 postProcessProperties接口
                            
                            PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                            if (pvsToUse == null) {
                                if (filteredPds == null) {
                                    filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                                }

                                pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                                if (pvsToUse == null) {
                                    return;
                                }
                            }

                            pvs = pvsToUse;
                        }
                    }
                }

                if (needsDepCheck) {
                    if (filteredPds == null) {
                        filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }

                    this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
                }

                if (pvs != null) {
                    this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
                }

            }
        }
    }

2、BeanPostProcessor接口

調用BeanPostProcessor接口在AbstractAutowireCapableBeanFactory 這類中 createBean->
initializeBean的接口中
(1)、BeanPostProcessor中的postProcessBeforeInitialization,postProcessAfterInitialization的接口

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        
        //BeanPostProcessor中的postProcessBeforeInitialization的調用
        
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }
        
		//BeanPostProcessor中postProcessAfterInitialization的調用
		
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

三、Aware類型的接口

Aware類型的接口主要是去Spring容器中的一些資源對應的資源。

在這裏插入圖片描述

1、Ware接口的調用在AbstractAutowireCapableBeanFactory 這類中 createBean->
initializeBean的接口中。

 protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
        //ware接口的調用
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
        
        //  //BeanPostProcessor中的postProcessBeforeInitialization的調用
        
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
        
        ////BeanPostProcessor中postProcessAfterInitialization的調用
        
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

AbstractAutowireCapableBeanFactory 這類中 createBean->
initializeBean->invokeAwareMethods,根據不同ware類型在不同spring容器拿不同的東西。

private void invokeAwareMethods(String beanName, Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware)bean).setBeanName(beanName);
            }

            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = this.getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
                }
            }

            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

    }

簡單的兩個生命週期接口

四、初始化和銷燬

1、初始化,初始化同樣在InitializingBean 對應生命週期的初始化階段,在上面源碼的invokeInitMethods(beanName, wrappedBean, mbd);方法中調用。

2、銷燬階段,銷燬的調用在AbstractApplicationContext類中的close()方法作

   public void close() {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.doClose();
            if (this.shutdownHook != null) {
                try {
                    Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
                } catch (IllegalStateException var4) {
                    ;
                }
            }

        }
    }

五、AbstractAutowireCapableBeanFactory 的父級入口

我們調用測試的時候需要一些入口,AbstractAutowireCapableBeanFactory 的調用在AbstractApplicationContext 中refresh接口中,定義了BeanPostProcesser和普通單例之間的加載順序。

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                
                 //BeanPostProcesser調用初始點(BeanPostProcesser也是bean需要先將BeanPostProcesser進行註冊)
                 
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                
                // 所有單例非懶加載Bean的調用點,例如controller,service類
                
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

AbstractApplicationContext 中finishBeanFactoryInitialization是我們,例如controller,service類這種單例非懶加載的父級入口。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
        
        //從這beanFactory.getBean("conversionService", ConversionService.class) 
        //調用的AbstractAutowireCapableBeanFactory 進行初始化
        
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

這是BeanPostProcesser也是bean需要先將BeanPostProcesser進行註冊的入口

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();
        List<String> nonOrderedPostProcessorNames = new ArrayList();
        String[] var8 = postProcessorNames;
        int var9 = postProcessorNames.length;

        String ppName;
        BeanPostProcessor pp;
        for(int var10 = 0; var10 < var9; ++var10) {
            ppName = var8[var10];
            
            //判斷是否有實現PriorityOrdered,如果實現PriorityOrdered放到priorityOrderedPostProcessors
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
                
                    //判斷是否有實現Ordered,如果實現PriorityOrdered放到orderedPostProcessorNames
                    
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
            
            //既沒有實現PriorityOrdered,也沒有實現Ordered的類
            
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

    .......

BeanPostProcessor的啓動時機。分爲四個階段,第一階段context內置階段、第二階段priorityOrdered階段、第三階段Ordered階段、第四階段nonOrdered階段。

BeanPostProcessor實例化時候,自動依賴注入根據類型獲得需要注入的Bean時,會將某些符合條件的Bean(FactoryBean並且其FactoryBeanFactory已經實例化的)先實例化,如果此FacotryBean又依賴其他普通Bean,會導致該Bean提前啓動,造成誤傷(無法享受部分BeanPostProcessor的後處理,例如典型的auto-proxy)。可以將其提前啓動類的始化方法加上static,或者將其移出單獨爲其創建一個配置類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章