SpringIOC
2023-02-15 20:03:04 0 举报
AI智能生成
SpringIOC
作者其他创作
大纲/内容
IOC应用
基础
BeanFactory与ApplicationContext区别
BeanFactor是顶级接口,定义基础功能规范,ApplicationContext 是高级接口,具备BeanFactory全部功能。
具体区别如下:
具体区别如下:
- 继承 org.springframework.context.MessageSource 接口,提供国际化的标准访问策略。
- 继承 org.springframework.context.ApplicationEventPublisher 接口,提供强大的事件机制。
- 扩展 ResourceLoader ,可以用来加载多种 Resource ,可以灵活访问不同的资源。
- 对 Web 应用的支持。
启动 IoC 容器的⽅式
java环境
- ClassPathXmlApplicationContext:从类的根路径下加载配置⽂件(推荐使⽤)
- FileSystemXmlApplicationContext:从磁盘路径上加载配置⽂件
- AnnotationConfigApplicationContext:纯注解模式下启动Spring容器
web环境
实例化Bean的三种⽅式
使⽤⽆参构造函数
使⽤静态⽅法创建
使⽤实例化⽅法创建
使⽤静态⽅法创建
使⽤实例化⽅法创建
Bean⽣命周期
作用范围&生命周期
- 单例模式:singleton
- 对象出⽣:当创建容器时,对象就被创建了。
- 对象活着:只要容器在,对象⼀直活着。
- 对象死亡:当销毁容器时,对象就被销毁了。
- ⼀句话总结:单例模式的bean对象⽣命周期与容器相同。
- 多例模式:prototype
对象出⽣:当使⽤对象时,创建新的对象实例。 - 对象活着:只要对象在使⽤中,就⼀直活着。
- 对象死亡:当对象⻓时间不⽤时,被java的垃圾回收器回收了。
- ⼀句话总结:多例模式的bean对象,spring框架只负责创建,不负责销毁。
标签属性
id、class、name...
依赖注入xml配置 : set、构造器注入...
配置模式:纯注解&注解+xml& xml
高级特性
lazy-Init 延迟加载
提高容器启动和运转性能
提高容器启动和运转性能
FactoryBean 和 BeanFactory
BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,
具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;
具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;
实现FactoryBean接口 它⾃定义Bean的创建过程。如果要获取FactoryBean,需要在id之前添加“&”
后置处理器
BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean
注意:处理是发⽣在Spring容器的实例化和依赖注⼊之后。
注意:处理是发⽣在Spring容器的实例化和依赖注⼊之后。
- BeanFactory级别的处理,是针对整个Bean的⼯⼚进⾏处理,典型应⽤:PropertyPlaceholderConfigurer
- BeanDefinition对象:我们在 XML 中定义的 bean标签,Spring 解析 bean 标签成为⼀个 JavaBean,这个JavaBean 就是 BeanDefinition
- 注意:调⽤ BeanFactoryPostProcessor ⽅法时,这时候bean还没有实例化,此时 bean 刚被解析成
BeanDefinition对象
IOC源码深度剖析
Spring IoC容器初始化主体流程
IoC容器体系
IoC容器是Spring的核⼼模块,是抽象了对象管理、依赖关系管理的框架解决⽅案。
Spring IoC 容器继承体系需要使⽤哪个层次⽤哪个层次即可。不是把所有接口都放在BeanFactory
ApplicationContext 还继承了ResourceLoader、MessageSource
Spring IoC 容器继承体系需要使⽤哪个层次⽤哪个层次即可。不是把所有接口都放在BeanFactory
ApplicationContext 还继承了ResourceLoader、MessageSource
Bean⽣命周期关键时机点
详细见代码。创建⼀个类 Bean ,让其实现⼏个特殊的接⼝,并分别在接⼝实现的构造器、接⼝⽅法中
断点,观察线程调⽤栈,分析出 Bean 对象创建和管理关键点的触发时机。
断点,观察线程调⽤栈,分析出 Bean 对象创建和管理关键点的触发时机。
根据上⾯的调试分析,我们发现 Bean对象创建的⼏个关键时机点代码层级的调⽤都在
AbstractApplicationContext 类 的 refresh ⽅法中,可⻅这个⽅法对于Spring IoC 容器初始化来说相当
关键,汇总如下:
构造器 - refresh#finishBeanFactoryInitialization(beanFactory)(beanFactory)
BeanFactoryPostProcessor 初始化refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanFactoryPostProcessor ⽅法调⽤refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanPostProcessor 初始化registerBeanPostProcessors(beanFactory)
BeanPostProcessor ⽅法调⽤refresh#finishBeanFactoryInitialization(beanFactory)
AbstractApplicationContext 类 的 refresh ⽅法中,可⻅这个⽅法对于Spring IoC 容器初始化来说相当
关键,汇总如下:
构造器 - refresh#finishBeanFactoryInitialization(beanFactory)(beanFactory)
BeanFactoryPostProcessor 初始化refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanFactoryPostProcessor ⽅法调⽤refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanPostProcessor 初始化registerBeanPostProcessors(beanFactory)
BeanPostProcessor ⽅法调⽤refresh#finishBeanFactoryInitialization(beanFactory)
子主题
IoC容器初始化主流程(refresh)
第⼀步:刷新前的预处理 prepareRefresh();
第⼆步:获取BeanFactory;默认实现是DefaultListableBeanFactory
加载BeanDefition 并注册到 BeanDefitionRegistry
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
加载BeanDefition 并注册到 BeanDefitionRegistry
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加
载器等)
prepareBeanFactory(beanFactory);
载器等)
prepareBeanFactory(beanFactory);
第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作
postProcessBeanFactory(beanFactory);
postProcessBeanFactory(beanFactory);
第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
invokeBeanFactoryPostProcessors(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执
⾏
registerBeanPostProcessors(beanFactory);
⾏
registerBeanPostProcessors(beanFactory);
第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
initMessageSource();
第⼋步:初始化事件派发器
initApplicationEventMulticaster();
initApplicationEventMulticaster();
第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
onRefresh();
onRefresh();
第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean
registerListeners();
registerListeners();
第⼗⼀步:
初始化所有剩下的⾮懒加载的单例bean
初始化创建⾮懒加载⽅式的单例Bean实例(未设置属性)
填充属性
初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法)
调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处
finishBeanFactoryInitialization(beanFactory);
初始化所有剩下的⾮懒加载的单例bean
初始化创建⾮懒加载⽅式的单例Bean实例(未设置属性)
填充属性
初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法)
调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处
finishBeanFactoryInitialization(beanFactory);
第⼗⼆步:
完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事
件 (ContextRefreshedEvent)
finishRefresh();
完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事
件 (ContextRefreshedEvent)
finishRefresh();
BeanFactory创建流程
获取BeanFactory⼦流程
BeanDefinition加载解析及注册⼦流程
Resource定位:指对BeanDefinition的资源定位过程。通俗讲就是找到定义Javabean信息的XML⽂
件,并将其封装成Resource对象。
件,并将其封装成Resource对象。
子主题
BeanDefinition载⼊ :把⽤户定义好的Javabean表示为IoC容器内部的数据结构,这个容器内部的数
据结构就是BeanDefinition。
据结构就是BeanDefinition。
Bean创建流程
finishBeanFactoryInitialization,创建子流程入口
beanFactory.preInstantiateSingletons() 实例化所有,立即加载单例bean
最后跟到AbstractBeanFactory类的doGetBean⽅法
最后调用 initializeBean
beanFactory.preInstantiateSingletons() 实例化所有,立即加载单例bean
最后跟到AbstractBeanFactory类的doGetBean⽅法
最后调用 initializeBean
lazy-init 延迟加载机制原理
lazy-init 延迟加载机制分析
- Spring 启动的时候会把所有bean信息(包括XML和注解)解析转化成Spring能够识别的BeanDefinition并存到Hashmap⾥供下⾯的初始化时⽤,然后对每个BeanDefinition 进⾏处理。
- 如果是懒加载的则在容器初始化阶段不处理,其他的则在容器初始化阶段进⾏初始化并依赖注⼊。最后通过外部getBean调用。
preInstantiateSingletons() 下 !bd.isLazyInit() 判断懒加载,是否需要初始化。普通Bean 直接调用getBean
总结
- 对于被修饰为lazy-init的bean Spring 容器初始化阶段不会进⾏ init 并且依赖注⼊,当第⼀次
进⾏getBean时候才进⾏初始化并依赖注⼊ - 对于⾮懒加载的bean,getBean的时候会从缓存⾥头获取,因为容器初始化阶段 Bean 已经
初始化完成并缓存了起来
Spring IoC循环依赖问题
0 条评论
下一页