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

水稻:啥?说人话?

菜瓜:spring,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(生命周期)的更多相关文章

  1. spring bean 容器的生命周期是什么样的?

    spring bean 容器的生命周期流程如下: 1.Spring 容器根据配置中的 bean 定义中实例化 bean. 2.Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置. 3 ...

  2. spring Bean的完整生命周期

    spring 容器中的bean的完整生命周期一共分为十一步完成. 1.bean对象的实例化 2.封装属性,也就是设置properties中的属性值 3.如果bean实现了BeanNameAware,则 ...

  3. 一张图搞懂Spring bean的完整生命周期

    一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任何一个环节怎么操作bean的生成及修饰是非常有帮助的. ...

  4. Spring Bean各阶段生命周期的介绍

    一.xml方式配置bean 二.Aware接口 2.1 BeanNameAware 2.2 BeanFactoryAware 2.3 ApplicationContextAware 2.4 Aware ...

  5. [spring] -- bean作用域跟生命周期篇

    作用域 singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的. prototype : 每次请求都会创建一个新的 bean 实例. request : 每一次HT ...

  6. Spring中与bean有关的生命周期

    前言 记得以前的时候,每次提起Spring中的bean相关的生命周期时,内心都无比的恐惧,因为好像有很多,自己又理不清楚,然后看网上的帖子,好像都是那么一套,什么beanFactory啊,aware接 ...

  7. Spring 了解Bean的一生(生命周期)

    转载 https://blog.csdn.net/w_linux/article/details/80086950 该篇博客就来了解IoC容器下Bean的一生吧,也可以理解为bean的生命周期. ## ...

  8. Spring注解开发系列Ⅲ --- 生命周期

    Bean的生命周期 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解. 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: S ...

  9. Bean 注解(Annotation)配置(2)- Bean作用域与生命周期回调方法配置

    Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...

随机推荐

  1. 那些面试官必问的JAVA多线程和并发面试题及回答

    Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环 ...

  2. HotRing: A Hotspot-Aware In-Memory Key-Value Store(FAST ’20)

      本文主要解决的是基于内存的K-V存储引擎在实际应用中出现的热点问题,设计了一个热点可感知的KV存储引擎,极大的提升了KV存储引擎对于热点数据访问的承载能力. Introduction 热点问题,可 ...

  3. .net remoting(一)

    一.远程对象 ①RemoteHello.csproj 类库项目,程序集名称 RemoteHello ,默认命名空间 Wrox.ProCSharp.Remoting: ②派生自System.Marssh ...

  4. 基于GTID搭建主从MySQL

    目录 基于gtid搭建主从MySQL 一.GTID的使用 二.GTID的简介 三.GTID的构成 四.查看GTID的执行情况 4.1 gtid_executed 4.2 gtid_own 4.3 gt ...

  5. 进程调度函数scheduler_tick()的触发原理:周期PERIODIC定时器

    参考文章: https://www.jb51.net/article/133579.htm https://blog.csdn.net/flaoter/article/details/77509553 ...

  6. Java实现 LeetCode 720 词典中最长的单词(字典树)

    720. 词典中最长的单词 给出一个字符串数组words组成的一本英语词典.从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成.若其中有多个可行的答案,则返回答案中字典序最 ...

  7. Java实现 LeetCode 587 安装栅栏(图算法转换成数学问题)

    587. 安装栅栏 在一个二维的花园中,有一些用 (x, y) 坐标表示的树.由于安装费用十分昂贵,你的任务是先用最短的绳子围起所有的树.只有当所有的树都被绳子包围时,花园才能围好栅栏.你需要找到正好 ...

  8. Java实现 LeetCode 540 有序数组中的单一元素(位运算入门)

    540. 有序数组中的单一元素 给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数. 示例 1: 输入: [1,1,2,3,3,4,4,8,8] 输出: 2 示例 ...

  9. Java实现 蓝桥杯VIP 算法训练 最长字符串

    题目描述 字符串可是比赛经常出的问题,那么给大家出一个题, 输入五个字符串,输出5个字符串当中最长的字符串.每个字符串长度在100以内,且全为小写字母. 输入 无 输出 无 样例输入 one two ...

  10. Java实现 LeetCode 258 各位相加

    258. 各位相加 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数. 示例: 输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2. 由 ...