【Spring】IOC的核心原理配方
引言
>IOC就是让对象不再自己new依赖,而是通过容器送进来
文章目录
引言
一、IOC
1.1 BeanFactory
1.2 XML应用
二、Bean实例流程
2.1 基本流程
2.2 后处理器
2.2.1 Bean工厂后处理器
2.2.2 Bean后处理器
2.3 Bean生命周期
2.3.1 三级缓存
2.3.2 三级缓存源码
2.4 Aware接口
三、Mybatis整合
3.1 基本使用
3.2 源码追踪
一、IOC
1.1 BeanFactory
beanFactory简单案例:
applicationContext简单案例:
源码查看会发现,applicationContext实现类内部其实也包含beanFactory属性
同时applicationContext也继承了beanFactory接口
1.2 XML应用
getBean方法是通过name去寻找bean的,默认使用id,但是也可以通过name1配置别名
当设置bean的范围scope="prototype"时,就不会初始化在单例池中
bean对象的执行顺序:实例化 > 属性赋值 > init初始化
静态工厂方法实例化Bean:
实例化工厂方法实例化Bean
实现FactoryBean接口实例化Bean(工程Bean)
此时查看单例池会发现类型变成了工厂实例
只有首次用的该roleBean时,才会调用getObject方法,缓存实例对象
beans标签的配置选择基本使用
二、Bean实例流程
2.1 基本流程
加载xml文件,封装成BeanDefinition对象存储在beanDefinitionMap中,ApplicationContext遍历map去创建Bean实例对象存储在singletonObjects中。
源码查看:
2.2 后处理器
Spring的后处理器是Spring对外开发的重要扩展点,允许我们介入到Bean的整个实例化流程中来,以达到动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用。
2.2.1 Bean工厂后处理器
BeanFactoryPostProcessor在BeanDefinitionMap填充完毕,Bean实例化之前执行。
或者第二种方案,实现BeanDefinitionRegistryPostProcessor接口
实现一个简单的注解注入bean
2.2.2 Bean后处理器
初始化的顺序:
2.3 Bean生命周期
简单来说分为三个阶段:实例化 > 初始化 > 完成
spring在进行属性填充时,会分为下面三种情况:
1.注入普通属性,直接通过set方法反射注入进入;
2.注入单向对象引用属性,先去容器中getBean获取实例在set进去,如果未找到就先创建被注入的bean实例再完成注入;
3.循环依赖问题,双向对象引用属性。
2.3.1 三级缓存
一级缓存singletonObjects:最终存储成品bean的容器
二级缓存earlySingletonObjects:存储半成品,且当前对象已被其他对象引用
三级缓存singletonFactories:存储半成品,对象未被引用,一开始存储地点
基本图解流程:
文字描述:实例化Service后存储三级缓存,进入属性填充步骤需要引用Dao,于是去一二三级逐级获取Dao,此时未找到该对象;就去实例化Dao,再去一二三级缓存中获取Service注入Dao中,Dao经过其他周期后存储到一级缓存,同时删除二三级的Dao,最后Service注入Dao完成实例化存储到一级缓存,删除二三级缓存的Service。
2.3.2 三级缓存源码
于是又执行一次getBean去创建userService实例对象,再将userDao从三级缓存注入到userService
还有一个存储三级缓存的代码,没找到,有没有大佬告知在哪里。
2.4 Aware接口
Aware接口就是Spring提供感知容器能力的机制,一般实现了XXXAware后就拥有了主动访问XXX能力。
三、Mybatis整合
3.1 基本使用
3.2 源码追踪
spring启动,触发MapperScannerConfigurer,MapperScannerConfigurer执行接口BeanDefinitionRegistryPostProcessor的实现方法postProcessBeanDefinitionRegistry
创建ClassPathMapperScanner对象,执行父类的scan方法,scan方法再去调用子类重写的doScan方法。为每个mapper接口创建一个Beandefinition对象,并将这个beandefinition对象的beanClass指向为MapperFactoryBean类型。
当spring创建其他bean时,发现需要依赖对应的mapper和sqlSessionFactory时;spring首先会去通过执行InitializingBean接口的afterProjpertiesSet实现方法;buildSqlSessionFactory会去创建对象,解析执行XML内容,最后创建出重量级的sqlSessionFactory。
接着spring去创建MapperFactoryBean,将sqlSessionFactory注入到mapperFactoryBean中,调用接口FactoryBean的实现方法getObject,通过jdk的动态代理创建一个实现了对应Mapper接口的代理对象