【Spring】Bean的LifeCycle生命周期

菜瓜:水稻,上次说Bean的LifeCycle,还没讲完

水稻:啥?说人话?

菜瓜:spring,bean,生命周期

水稻:。。。那你真的是很棒棒哦!。。。bean生命周期的话,从BeanFactory、ApplicationContext和FactoryBean开始说起

我们知道(你不一定知道)BeanFactory是Spring访问Bean容器的根接口,源码的注释: “The root interface for accessing a Spring bean container.”
而ApplicationContext继承自BeanFactory,也就是说它具有BeanFactory的属性和方法,并进一步完善(继承其他的接口)
FactoryBean跟前两个关系就不怎么大了,它是spring提供给用户创建bean的口子,有一些bean创建过程复杂,或者依赖第三方包等(Mybatis-Spring中),可交给用户自己创建

菜瓜:嗯。。陷入沉思。。(欲言又止)

水稻:讲理论不给代码就是耍流氓

package com.vip.qc.postprocessor;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

/**
 * @author QuCheng on 2020/6/15.
 */
@Component"fb")
public class FactoryBeanT implements FactoryBean<FactoryBeanT.CustomBean> {

    public FactoryBeanT) {
        System.out.println"实现FactoryBean接口的类自身被放在IOC一级缓存的容器里面,getObject的对象是在另一个缓存对象中");
    }

    @Override
    public CustomBean getObject) {
        return new CustomBean);
    }

    @Override
    public Class<?> getObjectType) {
        return CustomBean.class;
    }

    static class CustomBean {
        public CustomBean) {
            System.out.println"自定义bean");
        }
    }
}

测试方法
@Test
public void testTransa) {
    BeanFactory context = new AnnotationConfigApplicationContextComponentScanD.class);
    System.out.println"factoryBean : " + context.getBean"fb"));
    System.out.println"&factoryBean : " + context.getBean"&fb"));
}

测试结果

  实现FactoryBean接口的类自身被放在IOC一级缓存的容器里面,getObject的对象是在另一个缓存对象中
  自定义bean
  factoryBean : com.vip.qc.postprocessor.FactoryBeanT$CustomBean@214b199c
  &factoryBean : com.vip.qc.postprocessor.FactoryBeanT@20d3d15a

菜瓜:懂了,BeanFactory是Spring的核心–容器,ApplicationContext则是包裹容器的上下文,丰富容器的功能(资源加载,事件驱动等)。FactoryBean也是Spring扩展性的体现

水稻:WC,你这个总结提到了精髓。就是扩展性:如果BeanFactory是核心思想,那么其他的上下文,后置处理器,还是Aware接口等等,都是为了实现扩展

菜瓜:铺垫说完了,开始生命周期呗

水稻:这次咱们反过来先看源码,再看实验,再总结

BeanFactory源码注释 – 定义了实现的生命周期

 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Chris Beams
 * @since 13 April 2001
 * @see BeanNameAware#setBeanName
 * @see BeanClassLoaderAware#setBeanClassLoader
 * @see BeanFactoryAware#setBeanFactory
 * @see org.springframework.context.ResourceLoaderAware#setResourceLoader
 * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
 * @see org.springframework.context.MessageSourceAware#setMessageSource
 * @see org.springframework.context.ApplicationContextAware#setApplicationContext
 * @see org.springframework.web.context.ServletContextAware#setServletContext
 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
 * @see InitializingBean#afterPropertiesSet
 * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
 * @see DisposableBean#destroy
 * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
 */
public interface BeanFactory {

BeanFactory源码实现类

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory

protected Object initializeBeanfinal String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if System.getSecurityManager) != null) {
            AccessController.doPrivilegedPrivilegedAction<Object>) ) -> {
                invokeAwareMethodsbeanName, bean);
                return null;
            }, getAccessControlContext));
        }
        else {
            // BeanNameAware BeanFactoryAware ...
            invokeAwareMethodsbeanName, bean);
        }

        Object wrappedBean = bean;
        if mbd == null || !mbd.isSynthetic)) {
            // BeanPostProcessor Before  @PostConstruct
            wrappedBean = applyBeanPostProcessorsBeforeInitializationwrappedBean, beanName);
        }

        try {
            // initMethod InitializingBean接口
            invokeInitMethodsbeanName, wrappedBean, mbd);
        }
        catch Throwable ex) {
            throw new BeanCreationException
                    mbd != null ? mbd.getResourceDescription) : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if mbd == null || !mbd.isSynthetic)) {
            // BeanPostProcessor after
            wrappedBean = applyBeanPostProcessorsAfterInitializationwrappedBean, beanName);
        }

        return wrappedBean;
    }

实验代码

package com.vip.qc.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * @author QuCheng on 2020/6/14.
 */
@Component
public class BeanFactoryPostProcessorT implements BeanFactoryPostProcessor {

    public static final String BEAN_NAME = "initializingBeanT";

    @Override
    public void postProcessBeanFactoryConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition initializingBeanT = beanFactory.getBeanDefinitionBEAN_NAME);
        System.out.println"BeanFactoryPostProcessor bean " + initializingBeanT.getBeanClassName));
    }
}



package com.vip.qc.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * @author QuCheng on 2020/6/14.
 */
@Component
public class BeanPostProcessorT implements BeanPostProcessor {

    public static final String BEAN_NAMET = "initializingBeanT";

    @Override
    public Object postProcessBeforeInitializationObject bean, String beanName) throws BeansException {
        if BEAN_NAMET.equalsbeanName)) {
            InitializingBeanT processorT = InitializingBeanT) bean);
            System.out.println"BeanPostProcessor BeforeInitialization " + processorT);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitializationObject bean, String beanName) throws BeansException {
        if BEAN_NAMET.equalsbeanName)){
            InitializingBeanT processorT = InitializingBeanT) bean);
            System.out.println"BeanPostProcessor AfterInitialization " + processorT);
        }
        return bean;
    }

}


package com.vip.qc.postprocessor;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @author QuCheng on 2020/6/14.
 */
@Component
public class InitializingBeanT implements BeanNameAware, InitializingBean, DisposableBean {

    public InitializingBeanT) {
        System.out.println"init无参构造 execute");
    }

    @PostConstruct
    public void postConstruct) {
        System.out.println"@PostConstruct  execute");
    }

    @PreDestroy
    public void preDestroy) {
        System.out.println"@PreDestroy  execute");
    }

    @Override
    public void afterPropertiesSet) {
        System.out.println"InitializingBean afterPropertiesSet --> " + this.toString));
    }

    @Override
    public void setBeanNameString name) {
        System.out.println"BeanNameAware : " + name);
    }

    @Override
    public void destroy) {
        System.out.println"destroy");
    }
}


测试代码
    @Test
    public void testLifeCycle) {
        AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContextComponentScanD.class);
        applicationContext.close);// 这里不关闭容器的话,注销bean的方法会看不到打印
    }

测试结果

  BeanFactoryPostProcessor bean com.vip.qc.postprocessor.InitializingBeanT
  init无参构造 execute
  BeanNameAware : initializingBeanT
  BeanPostProcessor BeforeInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
  @PostConstruct execute
  InitializingBean afterPropertiesSet –> com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
  BeanPostProcessor AfterInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
  @PreDestroy execute
  destroy

菜瓜:实现什么的不重要,接口才是爸爸呀,BeanFactory定义好了生命周期,下面的实现也只是实现罢了

水稻:哈哈,你说的对,一流的公司卖标准

菜瓜:这里怎么没看到循环依赖的处理啊

水稻:是的。这里的源码我只截取了bean初始化完成之后的接口调用。循环依赖的处理在它前面。来来来,继续刚

菜瓜:刚不了刚不了,你一下子搞这么多玩意给我看,我哪看得完

水稻:您歇着,下次您什么时候想了解我再给您说

总结

BeanFactory已经定义了整个的生命周期,子类只是负责实现,demo演示也只是为了证实。我们更应该关注更上层的东西 
ApplicationContext是对容器更精细化的包装,提供了更完善的功能
FactoryBean是Spring扩展性的提现,可供用户自己定义创建bean。扩展性提炼的很好

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注