首页 科技正文

《唐山工》业职业技术《学院》:Spring Bean{的生命周期}

admin 科技 2020-06-01 22 1
深度报道:Webpack【实战】(八):教你搞懂webpack〖{如}果〗实现代码分片(code splitting)

《一》、引言

  《要想理解》Spring框架,〖那么〗Spring Bean{「<《的》>」生命周期}就是必须要了解「<《的》>」《一》环,『『关于』』Spring Bean{「<《的》>」生命周期},就是《一》个Bean<在>IOC容器中从创建到“销”毁「<《的》>」过程,下面就开始梳理《一》下《一》个Bean「「<《的》>」创建过」程。

二、生命周期概要流程

  <简单「<《的》>」来说>,《一》个Bean{「<《的》>」生命周期}分为四个阶段:

  1、(实例化)(Instantiation)

  2、〖属性设置〗(populate)

  3、「‘初始化’」(Initialization)

  4、“销”毁(Destruction)

『〖{如}下〗图』:

  (具体逻辑位于)AbstractAutowireCapableBeanFactory类doCreateBean『「【「【方】法」】」中』,代码较多,只放出了重要「<《的》>」部分,〖{如}下〗:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;

        if (instanceWrapper == null) {
            //(实例化)
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        try {
            //《属性赋值》
            this.populateBean(beanName, mbd, instanceWrapper);
            //「‘初始化’」
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            //...
        }

        try {
            //{注册“销”毁回调 接[口}
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            //...
        }
    }

   <上面是「<《的》>」步(实例化)>、《属性赋值》、「‘初始化’」都是Spring容器启动时「<《的》>」步骤,“销”毁是<在>容器关闭时「<《的》>」操作,【容器“销”毁时会调用容器「<《的》>」】close()「【「【方】法」】」去“销”毁容器。

三、对生命周期「<《的》>」扩展

  Spring<在>创建Bean「<《的》>」时候不仅仅只创建了《一》个我们设置「<《的》>」Bean,还可以<在>创建Bean〖「<《的》>」时候对它进行很多「<《的》>」扩〗展,总「<《的》>」来说有以下几类:

  1、BeanPostProcessor 接[口

  2、InstantiationAwareBeanPostProcessor 接[口

  3、Aware类型「<《的》>」 接[口

双鸭山租房信息:C#「「<《的》>」静态工厂「【「【方】法」】」与构造」函数对比

  4、生命周期类型 接[口

   其中[1「和」2是作用于所有Bean「<《的》>」 接[口,3「和」4是作用于单个Bean「<《的》>」 接[口。BeanPostProcessor是「‘初始化’」时「<《的》>」后置处理器,InstantiationAwareBeanPostProcessor「是实」例化时「<《的》>」后置处理器,Aware类型「<《的》>」 接[口{如}BeanNameAware、BeanFactoryAware等需要Bean{自己去实现},生命周期类型 接[口{如}InitializingBean、DisposableBean。

   加上这些扩展[,现<在>上面「<《的》>」图可以变成下面这样了:

   接下来看详细「<《的》>」源码,<刚刚我们提到「<《的》>」实例>化、《属性赋值》、「‘初始化’」这三个步骤都<在>doCreateBean『「【「【方】法」】」中』,〖那么〗<在>这个「【「【方】法」】」之前有什么操作吗:

    //createBean<「【「【方】法」】」里面调用了>doCreateBean
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        Object beanInstance;
        try {
            //这个里面调用了InstantiationAwareBeanPostProcessor({「<《的》>」前置「【「【方】法」】」})postProcessBeforeIns
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
        } catch (Throwable var10) {
            //...
        }
        //...
        try {
            //这里调用了doCreateBean
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            //...
        } catch (Throwable var8) {
            //...
        }
    }

    //resolveBeforeInstantiation<「【「【方】法」】」里面调用了>这个「【「【方】法」】」
    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 ibp = (InstantiationAwareBeanPostProcessor)bp;
                //调用了InstantiationAwareBeanPostProcessor({「<《的》>」前置「【「【方】法」】」})postProcessBeforeInstantiation
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

  <在>调用完InstantiationAwareBeanPostProcessor({「<《的》>」前置「【「【方】法」】」})之后接下来进入doCreateBean「【「【方】法」】」, 首先会‘「执行」’[createBeanInstance(beanName, mbd, args)进行(实例化),{然后进入}populateBean(beanName, mbd, instanceWrapper)「【「【方】法」】」进行《属性赋值》,看《一》下这《一》部分代码还有没有别「<《的》>」操作:

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            //...
        } else {
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var4 = this.getBeanPostProcessors().iterator();

                while(var4.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var4.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        
                        //‘「执行」’InstantiationAwareBeanPostProcessor「<《的》>」后置「【「【方】法」】」postProcessAfterInstantiation
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            return;
                        }
                    }
                }
            }
            if (hasInstAwareBpps) {
                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) {
                            
                            ////‘「执行」’‘「执行」’InstantiationAwareBeanPostProcessor「<《的》>」postProcessPropertyValues(该「【「【方】法」】」已废弃, 不建议使用[)
                            pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        }
                    }
                }
            }

        }
    }

  通过源码可以看出InstantiationAwareBeanPostProcessor「<《的》>」几个「【「【方】法」】」分别<在>(实例化)「<《的》>」前后完成,然后进行《属性赋值》,『接下来就是(实例化)』initializeBean(beanName, exposedObject, mbd),我们来看《一》下:

    //该「【「【方】法」】」位于AbstractAutowireCapableBeanFactory《类中》,「这段代码很简单」,不像其他部分还添加了很多其他操作,这块《一》看就明白了,就不把BeanPostProcessor、InitializingBean等具体「<《的》>」「【「【方】法」】」列出来了
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                //invokeAwareMethods「【「【方】法」】」‘「执行」’实现「<《的》>」Aware 接[口
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            //「和」上面「<《的》>」《一》样,‘「执行」’实现「<《的》>」Aware类型「<《的》>」 接[口
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //这个「【「【方】法」】」里面‘「执行」’了BeanPostProcessor「<《的》>」postProcessBeforeInitialization「【「【方】法」】」
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            //‘「执行」’了InitializingBean「<《的》>」afterPropertiesSet「【「【方】法」】」「和」自定义「<《的》>」init-method「【「【方】法」】」
            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;
    }

  『『关于』』Aware类型「<《的》>」 接[口这里要说《一》下,可能你会奇怪按照我上面「<《的》>」那个类去找invokeAwareMethods(beanName, bean)「【「【方】法」】」会是下面这种情况:

    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);
            }
        }

    }

  为什么只有这三个Aware类型「<《的》>」 接[口,明明还有其他好几种啊,【比{如}】EnvironmentAware、EmbeddedValueResolverAware等,这是什么它们「<《的》>」容器不同,AbstractAutowireCapableBeanFactory使用「<《的》>」容器是BeanFactory,其他几种是ApplicationContext 添加「<《的》>」扩展 接[口,{如}:

    //ApplicationContextAwareProcessor中实现「<《的》>」 接[口〖{如}下〗
    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);
        }

    }

  到这《一》步「‘初始化’」也完成了,至于“销”毁时<在>容器关闭时‘「执行」’容器「<《的》>」close「【「【方】法」】」,close『「【「【方】法」】」中』会‘「执行」’destroy「【「【方】法」】」“销”毁所有「<《的》>」Bean:

    //“销”毁Bean「<《的》>」「【「【方】法」】」
    public void destroy() {
        if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
            Iterator var1 = this.beanPostProcessors.iterator();

            while(var1.hasNext()) {
                //其实这里也有个“销”毁时「<《的》>」处理器,实现了BeanPostProcessor,<在>‘「执行」’“销”毁「【「【方】法」】」前‘「执行」’postProcessBeforeDestruction「【「【方】法」】」
                DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor)var1.next();
                processor.postProcessBeforeDestruction(this.bean, this.beanName);
            }
        }

        if (this.invokeDisposableBean) {

            try {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(() -> {
                        //‘「执行」’DisposableBean「<《的》>」destroy「【「【方】法」】」
                        ((DisposableBean)this.bean).destroy();
                        return null;
                    }, this.acc);
                } else {
                    //【同上】,‘「执行」’DisposableBean「<《的》>」destroy「【「【方】法」】」
                    ((DisposableBean)this.bean).destroy();
                }
            } catch (Throwable var3) {
                //...
            }
        }

        if (this.destroyMethod != null) {
            //{如}果存<在>指定「<《的》>」“销”毁「【「【方】法」】」就‘「执行」’,《即》destroy-method指定「<《的》>」「【「【方】法」】」
            this.invokeCustomDestroyMethod(this.destroyMethod);
        } else if (this.destroyMethodName != null) {
            //...
        }

    }

  到这里我们已经看完了《一》个Bean从(实例化)到“销”毁「<《的》>」所有步骤。

四、〖总结〗

  总「<《的》>」来说Spring Bean{「<《的》>」生命周期}就是四大步骤,(实例化) -> 《属性赋值》 ->「‘初始化’」 ->“销”毁,其他「<《的》>」操作都是对这四个步骤「<《的》>」扩展。

,

诚信<在>线

诚信<在>线(www.chengxin11.cn)现已开放诚信<在>线手机版下载。『游戏公平』、公开、公正,用实力赢取信誉。

版权声明

本文仅代表作者观点,
不代表本站Sunbet的立场。
本文系作者授权发表,未经许可,不得转载。

评论

精彩评论
  • 2020-06-01 00:02:00

    联博统计www.tjdltrade.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。哈哈,好欢乐