5、Spring Bean的生命周期以及整合第三方框架

Spring Bean的生命周期

Bean实例的属性填充

 

注入单向对象引用属性时

情况一,被注入的引用对象先于创建

 情况二,被注入的引用对象后于创建

 可以看到,情况二的时候,加载xml文件将<bean>包装进beanDefinitionMap后,是按顺序取出bean信息进行创建的,如果创建时需要的引用依赖未被加载进容器,则会暂停当前bean的生命周期,先去创建需要的那个引用依赖对应的bean。

注入双向对象引用属性时

多个实体之间相互依赖并形成闭环的情况就叫做“循环依赖”,也叫“循环引用”。

如下图,getBean("userService")后,先实例化Service,开辟内存给一个地址用于存储半成品的Service,然后继续执行bean的生命周期,对Service初始化,填充引用对象userDao,但是没有userDao,就先暂停userService的生命周期,改去执行userDao的生命周期,但是userDao初始化也要填充引用对象userService,这样看起来就变成了一个死循环的问题。

但其实, 其中一方在填充对方的bean时,可以引用对方bean的内存地址,然后对方生命周期执行完了之后,因为地址在咱这,对方依然是咱的人,这和等对方初始化完了之后再给咱是一样的,最终都是那同一个在实例化之初就开辟好的地址。这样就结束了所谓的死循环,即将半成品的未初始化的bean先存在某处(反正不是单例池)。

 

 真正的解决方法!!!

三级缓存,将完整Bean实例和半成品Bean实例分开存储,当Bean初始化要注入引用类型时,先去完整Bean实例的地方寻找,没有的话再去半成品Bean实例寻找,这样就可以解决循环引用问题。

 在DefaultSingletonBeanRegistry的源码中,有:

singletonObjects(我们属性的最终存储单例Bean成品的单例池,在这里被称为一级缓存),

sigletonFactories(早期单例池,缓存已被引用的半成品对象,被称为二级缓存),

earlySingletonObjects(也是早期单例池,缓存创建完毕初始化未完成未被引用的半成品对象,被称为三级缓存)

 循环依赖解决方案的描述:

 Aware接口

要导包 

 IoC容器实例化Bean整体流程分析

当ApplicationContext容器初始化时,BeanDefinitionReader读取器读取xml文件中的<bean>标签,并将每个<bean>标签的信息抽取封装到BeanDefinition对象中,BeanDefinition对象会被存储到beanDefinitionMap中,最终Spring容器遍历beanDefinitionMap,通过反射创建每一个bean实例对象,把对象存储在singletonObjects单例池中,当执行getBean时,就回去单例池中寻找单例对象。

 Bean工厂后处理器

 Bean后处理器

 

 Spring整合第三方框架

Spring整合Mybatis

一般使用Mybatis:

准备测试用的数据表

编写实体类对象

编写Mapper接口

编写Mapper对应xml文件

配置mybatis-config配置文件

 编写启动类

 Spring整合Mybatis:

 导入Maven坐标,前两个分别为mysql连接jar和mybatis坐标,后两个为Spring为Mybatis整合进Spring提供的坐标。

目的是将mybatis-config这个Mybatis配置类中配置源以及扫描mapper包配置到xml文件中:

 配置数据源:

配置扫描Mapper包: 

使用时,在需要mapper接口的地方直接注入即可:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值