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