• Bean的生命周期


    Spring Bean 的生命周期是从 Bean 实例化之后,即通过反射创建出对象之后,到 Bean 成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean 的生命周期。

    一,实例化

    1.1Bean工厂后处理器 – BeanFactoryPostProcessor

    BeanFactoryPostProcessor 是一个接口规范,实现了该接口的类只要交由 Spring 容器管理的话,那么 Spring就会回调该接口的方法,用于对BeanDefinition 注册 修改 的功能。

    1.1.1修改Bean

    修改已经经过加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象====》存储在名为beanDefinitionMapMap中。

    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("MyBeanFactoryPostProcessor的postProcessBeanFactory");
            BeanDefinition beanDefinition=beanFactory.getBeanDefinition("user");
            beanDefinition.setBeanClassName("com.apesource.pojo.Student");}
    }
    

    applicationcontext.xml中的内容。

    
    

    //运行结果 

    MyBeanFactoryPostProcessor的postProcessBeanFactory
    com.apesource.pojo.Student@1ed4004b

    //结果分析

    注册的是user的bean,但是经过BeanFactoryPostProcessor重新将BeanclassName修改过后,变成了student的bean。

    1.1.2 注册一个Bean的方法一

    如何利用BeanFactoryPostProcessor注册一个Bean

    //注册演示
            BeanDefinition beanDefinition1 = new RootBeanDefinition();
            beanDefinition1.setBeanClassName("com.apesource.pojo.Student");
    //强转成DefaultListableBeanFactory
            DefaultListableBeanFactory defaultListableBeanFactory =              (DefaultListableBeanFactory) beanFactory;
            defaultListableBeanFactory.registerBeanDefinition("stu2",beanDefinition1);

    在xml中并没有注册stu2,但是在getBean的时候,可以得到student的实体类对象

    1.1.3 注册一个Bean的方法二 

    Bean工厂后处理器 – BeanDefinitionRegistryPostProcessor 

    Bean 工厂后处理器 – BeanDefinitionRegistryPostProcessor Spring 提供了一个 BeanFactoryPostProcessor 的子接口 BeanDefinitionRegistryPostProcessor 专门用于注册 BeanDefinition 操作。
    1. public class MyBeanFactoryPostProcessor2 implements
    2. BeanDefinitionRegistryPostProcessor {
    3. @Override
    4. public void postProcessBeanFactory(ConfigurableListableBeanFactory
    5. configurableListableBeanFactory) throws BeansException {}
    6. @Override
    7. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry
    8. beanDefinitionRegistry) throws BeansException {
    9. BeanDefinition beanDefinition = new RootBeanDefinition();
    10. beanDefinition.setBeanClassName("com.apesource.pojo.Student");
    11. beanDefinitionRegistry.registerBeanDefinition("stu",beanDefinition);
    12. }
    13. }

    Bean被实例化后,会经过初始化

    二,初始化

    2.1BeanPostProcessor(Bean后处理)

    BeanPostProcessor,是 Bean 后处理。
    1. //1.自定义MyBeanPostProcessor
    2. public class MyBeanPostProcessor implements BeanPostProcessor {
    3. /* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
    4. 返回值:当前Bean实例对象 */
    5. public Object postProcessBeforeInitialization(Object bean, String beanName)
    6. throws BeansException {
    7. System.out.println("BeanPostProcessor的before方法...");
    8. return bean;
    9. }
    10. /* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
    11. 返回值:当前Bean实例对象 */
    12. public Object postProcessAfterInitialization(Object bean, String beanName)
    13. throws BeansException {
    14. System.out.println("BeanPostProcessor的after方法...");
    15. return bean;
    16. }
    17. }
    18. //2.注入配置MyBeanPostProcessor
    19. <bean class="com.apesource.processors.MyBeanPostProcessor"></bean>
    20. //3.测试控制台打印结果如下
    21. User创建了...
    22. BeanPostProcessor的before方法...
    23. User属性填充...
    24. User初始化方法执行...
    25. BeanPostProcessor的after方法...
    26. com.apesource.pojo.User@56ac3a89

    2.2属性初始化

    2.2.1解决双向对象冲突(三级缓存)

    //1 、最终存储单例 Bean 成品的容器,即实例化和初始化都完成的 Bean ,称之为 " 一级缓存 "
    Map < String , Object > singletonObjects = new ConcurrentHashMap ( 256 );
    //2 、早期 Bean 单例池,缓存半成品对象,且当前对象已经被其他对象引用了,称之为 " 二级缓存 "
    Map < String , Object > earlySingletonObjects = new ConcurrentHashMap ( 16 );
    //3 、单例 Bean 的工厂池,缓存半成品对象,对象未被引用,使用时在通过工厂创建 Bean ,称之为 " 三级缓存"。
    Map < String , ObjectFactory > singletonFactories = new HashMap ( 16 );
    1. UserService 实例化对象,但尚未初始化,将UserService存储到三级缓存;
    2. UserService 属性注入,需要UserDao,从缓存中获取,没有UserDao
    3. UserDao实例化对象,但尚未初始化,将UserDao存储到到三级缓存;
    4.将出现矛盾的两个Bean,其中一个Bean(UserDao)要走另一条路径,完成自己的初始化。 从三级缓存到二级,最终到一级缓存, 供UserService调用。
    最终缓存到名为singletonObjects 单例池。

    三,调用

    getBean方法可以获取到serviceBean。getBean最终得到的都是完整的Bean

    四,销毁 

  • 相关阅读:
    TensorRT来加速YOLO v5推理与检测
    2021Java面试题及答案整理(最新汇总版)
    构建创新增值能力优势,康铂酒店突围中端酒店市场!
    Linux·串口编程
    GIT中对子仓库的使用方法介绍
    关于while和do-while结构
    AJAX——事件循环(EventLoop)
    React中的useEffect(副作用)
    横向知识总结
    分布式链路追踪 — Overview
  • 原文地址:https://blog.csdn.net/weixin_51704612/article/details/132969432