【Spring】Bean的LifeCycle(生命周期)

本文内容纲要:【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 AnnotationConfigApplicationContext(ComponentScanD.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 initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

    if (System.getSecurityManager() != null) {

    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {

    invokeAwareMethods(beanName, bean);

    return null;

    }, getAccessControlContext());

    }

    else {

    // BeanNameAware BeanFactoryAware ...

    invokeAwareMethods(beanName, bean);

    }

    Object wrappedBean = bean;

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

    // BeanPostProcessor Before @PostConstruct

    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

    }

    try {

    // initMethod InitializingBean接口

    invokeInitMethods(beanName, 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 = applyBeanPostProcessorsAfterInitialization(wrappedBean, 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 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    BeanDefinition initializingBeanT = beanFactory.getBeanDefinition(BEAN_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 postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

    if (BEAN_NAMET.equals(beanName)) {

    InitializingBeanT processorT = ((InitializingBeanT) bean);

    System.out.println("BeanPostProcessor BeforeInitialization " + processorT);

    }

    return bean;

    }

    @Override

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

    if (BEAN_NAMET.equals(beanName)){

    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 setBeanName(String name) {

    System.out.println("BeanNameAware : " + name);

    }

    @Override

    public void destroy() {

    System.out.println("destroy");

    }

    }

    测试代码

    @Test

    public void testLifeCycle() {

    AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(ComponentScanD.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。扩展性提炼的很好

本文内容总结:【Spring】Bean的LifeCycle(生命周期)

原文链接:https://www.cnblogs.com/nightOfStreet/p/13117806.html

以上是 【Spring】Bean的LifeCycle(生命周期) 的全部内容, 来源链接: utcz.com/z/362478.html

回到顶部