Spring 生命周期

实例化

1.加载配置文件

BeanDefinition Reader 组件配置文件,将每个Bean对象的所有信息存放到一个一个BeanDefinition对象当中;

2.存放到beanDefinitionMap中

将BeanDefinition存储在一个名为beanDefinitionMap的Map中;

3.执行BeanFactoryPostProcess接口实现类中的注册和修改方法

BeanFactoryPostProcess用于注册和修改

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

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

    }
}

BeanDefinitionRegistryPostProcessor 主要是去注册

public class MyBeanFactoryPostProcessor2 implements 
BeanDefinitionRegistryPostProcessor {
 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory 
configurableListableBeanFactory) throws BeansException {}
 @Override
 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry 
beanDefinitionRegistry) throws BeansException {
 BeanDefinition beanDefinition = new RootBeanDefinition();
 beanDefinition.setBeanClassName("com.apesource.pojo.Student");
 beanDefinitionRegistry.registerBeanDefinition("stu",beanDefinition);
 }
 }

4:获取Bean信息,创建半成品Bean对象

ApplicationContext底层遍历beanDefinitionMap,创建Bean半成品实例对象(由于其还没有注入它的属性值,只是创建了对象);

初始化

1,属性赋值

Spring在进行属性注入时,会分为如下几种情况:

注入普通属性,String、int或存储基本类型的集合时,直接通过set方法的反射设置进去;

注入单向对象引用属性时,从容器中getBean获取后通过set方法反射设置进去,如果容器中没 有,则先创建被注入对象Bean实例(完成整个生命周期)后,在进行注入操作;

注入双向对象引用属性时,就比较复杂了,涉及了循环引用(循环依赖)

2,执行实现了的Aware接口中的方法

Aware接口是一种框架辅助属性注入的一种思想,其他框架中也可以看到类似的接口。框架具备高度封 装性,我们接 触到的一般都是业务代码,一个底层功能API不能轻易的获取到,但是这不意味着永远用 不到这些对象,如果用到了 ,就可以使用框架提供的类似Aware的接口,让框架给我们注入该对象 总结:处理器的作用,为Bean生命周期各个阶段提供扩展

3,执行BeanPostProcesser接口实现类的before()方法

Bean后处理器 – BeanPostProcessor Bean被实例化后,到最终缓存到名为singletonObjects单例池之前,中间会经过Bean的初始化过程, 例如:属性 的填充、初始方法init的执行等,其中有一个对外进行扩展的点BeanPostProcessor,我们称为Bean后 处理。跟上 面的 Bean工厂后处理器相,也是一个接口,实现了该接口并被容器管理的BeanPostProcessor, 会在流程节点上被Spring自动调用。

4,执行InitializingBean接口初始化方法

5,执行自定义初始化方法

6,执行BeanPostProcesser接口实现类的After()方法

//1.自定义MyBeanPostProcessor
 public class MyBeanPostProcessor implements BeanPostProcessor {
 /* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
返回值:当前Bean实例对象 */
 public Object postProcessBeforeInitialization(Object bean, String beanName) 
throws BeansException {
 System.out.println("BeanPostProcessor的before方法...");
 return bean;
 }
 /* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
返回值:当前Bean实例对象 */
 public Object postProcessAfterInitialization(Object bean, String beanName) 
throws BeansException {
 System.out.println("BeanPostProcessor的after方法...");
 return bean;
 }
 }
 //2.注入配置MyBeanPostProcessor
 <bean class="com.apesource.processors.MyBeanPostProcessor"></bean>

getBean()调用

销毁

1,执行接口销毁方法

2,执行自定义销毁方法

Spring  Bean生命周期总结:

循环依赖问题:

  Bean对象A 依赖Bean对象B,同时Bean对象B依赖Bean对象A,即循环依赖

Spring解决:对Bean对象的存放设立三级缓存

Spring提供了三级缓存存储 完整Bean实例 和 半成品Bean实例 ,用于解决循环引用问题 在DefaultListableBeanFactory的上四级父类DefaultSingletonBeanRegistry中提供如下三个Map

public class DefaultSingletonBeanRegistry ... {
 //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);
 }

注:将对象保存至三级缓存的时候,会包装成ObjectFactory对象录入,未来通过此接口对应的get方法再
次提取对象

循环依赖eg:UserService和UserDao构成循环依赖

UserService和UserDao循环依赖的过程结合上述三级缓存描述一下

UserService 实例化对象,但尚未初始化,将UserService存储到三级缓存;

UserService 属性注入,需要UserDao,从缓存中获取,没有UserDao;

UserDao实例化对象,但尚未初始化,将UserDao存储到到三级缓存;

UserDao属性注入,需要UserService,从三级缓存获取UserService,

UserService从三级缓存移 入二级缓存;

UserDao执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存; UserService 注入UserDao; UserService执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓 存。

    二.spring对于bean的作用域

         含义:bean在spring容器中创建的策略以及访问的范围

         位置:bean标签属性位置

         语法:scope=""

            属性值:

                singleton========>单例模式====全局唯一====性能好====安全性低(默认方式)

                prototype========>多例模式====全局不唯一====性能不好====安全性高

                ============================以下作用域数据web模块===============================

                request========>一次请求创建一个对象

                session========>一个会话创建一个对象

    三.spring对于bean的生命周期管理

       单例模式:

            实例化=====>容器创建的时候实例化

            属性赋值

            初始化=====>实例化完成,则自动初始化

                     接口初始化:InitializingBean中的afterPropertiesSet

                     属性初始化:init-method属性绑定方法

            使用操作

            销毁======>容器关闭,单例的bean则自动销毁

                    接口销毁:DisposableBean

                    属性销毁:destroy-method="",完成资源回收

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值