面试真题--------spring源码解析IOC
spring是我经常使用的框架,可是你真的对spring理解吗? 还是只知道它得使用。如果你想知道它真实的面目请仔细向下看。
1.spring是如何知道哪些Bean需要实例化的?
容器启动过程中,首先调用DispatcherSerlvet的init方法,init方法内部根据web.xml的配置,读取配置的上下文readspring-servlet.xml,然后逐句解析该上下文,当它读取到context:component-scan标签时,就启动对应的解析器,也可以叫做扫描器,对应的Class为:ComponentScanBeanDefinitionParser。这个类ComponentScanBeanDefinitionParser中调用了doScan方法,可以看到传了一个参数:basePackages,就是我们配置的路径。
这样,就读取到了需要被实例化的所有类,之后这些类的信息会被封装成一个一个的BeanDefinition,然后保存到DefaultListableBeanFactory的beanDefinitionMap中供后续使用。
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
2.Spring中Bean是什么时候被实例化的?
所有的这些Bean,在容器启动的时候,已经全部被实例化了。
下面看代码一探究竟,还得看模板方法,AbstractApplicationContext.refresh(),其中有这么一个方法
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
看注释知道:实例化剩下的所有单例。
Spring中的Bean默认都是单例的,除非显示的声明为prototype。
剩下的(remaining)的意思是有一些Spring自身的处理器、解析器等Bean不是在这里实例化的,我们自己编写的常规类Controller、Service等全部都是在此处实例化。
3.实例化的过程
首先循环所有的BeanDefinition列表,然后调用getBean()方法,检查是否被实例化,如果没有被实例化则调用createBean()方法,具体的实例化是利用cglib类库,通过Java反射原理,构造函数实例化方式去实例化。然后组装Bean,把Bean属性设置进去,这里就是依赖注入了,把实例化好的serviceInstance注入到Service中。实例化成功后将实力保存到singletonObjects Map中。
所有的Bean被实例化后,会被存入这个Map中供后续使用。
DefaultSingletonBeanRegistry.java
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
4.Bean的Scope
(1)Singleton:一个Spring容器中只有一个Bean的实例,此为Spring的默认配置,全容器共享一个实例。
(2)Prototype:每次调用新建一个Bean实例。
(3)Request:Web项目中,给每一个 http request 新建一个Bean实例。
(4)Session:Web项目中,给每一个 http session 新建一个Bean实例。
(5)GlobalSession:这个只在portal应用中有用,给每一个 global http session 新建一个Bean实例。
其中request,session和global session只适用于Web应用程序中,通常是与XmlWebApplicationContext一起使用,在实现上,singleton和prototype两种类型的容器的标准类型,而Scope request,session和global session是继承于自定义的Scope接口,如果用户有特殊的需要,可以继承这个接口并注册到容器中,即可使用用户自定义的Scope类型。用户自定义的Scope必须自己维护所管辖对象的初始化及销毁,即容器将这些对象的生存周期委托给Scope管理,而容器只管理Scope对象本身就可以。
5. 注解怎么做到声明接口就可以将实现类注入?
Spring主要利用了Class.isAssignableFrom()方法来实现接口与实现类的匹配。
Class1.isAssignableFrom(Class2):如果Class1是Class2本身或者是其接口或者父类,则返回true,否则返回false;
以testService的实例化为例,当Spring容器启动的时候,首先会读取配置文件,经过定位、加载、解析、注册,最终把标注了注解的类(例如:标注了@Service的TestServiceImpl)注册到BeanDefination的Map中并且缓存。
然后,在实例化testService的时候,Spring此刻并不知道testService的实现类是哪个,而是循环遍历BeanDefinitionMap中的Bean,逐一与ITestService接口进行类型匹配,一旦匹配上就认定为其实现类,并对其进行实例化。
参考----http://www.cnblogs.com/notDog/p/5420727.html
https://www.cnblogs.com/dyppp/p/7397290.html
https://www.imooc.com/article/19601
面试真题--------spring源码解析IOC的更多相关文章
- 面试真题--------spring源码解析AOP
接着上一章对IOC的理解之后,再看看AOP的底层是如何工作的. 1.实现AOP的过程 首先我们要明白,Spring中实现AOP,就是生成一个代理,然后在使用的时候调用代理. 1.1 创建代理工厂 ...
- Spring源码解析-ioc容器的设计
Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...
- Spring源码解析-IOC容器的实现-ApplicationContext
上面我们已经知道了IOC的建立的基本步骤了,我们就可以用编码的方式和IOC容器进行建立过程了.其实Spring已经为我们提供了很多实现,想必上面的简单扩展,如XMLBeanFacroty等.我们一般是 ...
- Spring源码解析-IOC容器的实现
1.IOC容器是什么? IOC(Inversion of Control)控制反转:本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,即交给了IOC容器,Spring的IO ...
- Spring源码解析--IOC根容器Beanfactory详解
BeanFactory和FactoryBean的联系和区别 BeanFactory是整个Spring容器的根容器,里面描述了在所有的子类或子接口当中对容器的处理原则和职责,包括生命周期的一些约定. F ...
- spring源码浅析——IOC
=========================================== 原文链接: spring源码浅析--IOC 转载请注明出处! ======================= ...
- 面试必备:ArrayList源码解析(JDK8)
面试必备:ArrayList源码解析(JDK8) https://blog.csdn.net/zxt0601/article/details/77281231 概述很久没有写博客了,准确的说17年以来 ...
- Spring源码解析 - AbstractBeanFactory 实现接口与父类分析
我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegistry和SingletonBeanRegistry接口. 这边主要提供了 ...
- Spring源码解析系列汇总
相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...
随机推荐
- Java 开源 CMS :magnolia
Magnolia 是一个开源基于Java的Web内容管理系统(CMS),构建在Java内容知识库标准(JSR-170).在使用它的过程中,我发现它的界面确实很有特色:给人一种Win8的感觉.在此记录一 ...
- 简译《Dissecting SQL Server Execution Plans》——连载总入口
转载请注明出处 由于工作及学习需要,最近看了一下<Dissecting SQL Server Execution Plans>,这是少有的专门描述执行计划的优秀书籍,为了快速查找并供入门同 ...
- 查看Linux系统的平均负载
1.Linux系统的平均负载的概念 有时候我们会觉得系统响应很慢,但是又找不到原因,这时就要查看平均负载了,看它是否有大量的进程在排队等待.特定时间间隔内运行队列中的平均进程数可以反映系统的繁忙程度, ...
- Gradle 1.12用户指南翻译——第三十章. CodeNarc 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
- ITU-T Technical Paper: IP服务性能模型
本文翻译自ITU-T的Technical Paper:<How to increase QoS/QoE of IP-based platform(s) to regionally agreed ...
- 关于Service中bindService注意的几个问题
最近有用到Activity需要不断的从Service中获取数据,第一个想法肯定就是通过bind回调机制了,有几点概念模糊特此记录下: 单独使用bindService(),unbindService() ...
- SpriteBuilder代码中弱引用(weak)需要注意的地方
比如在GameScene类中有一个弹出菜单层实例的引用,我们有: @implementation GameScene{ //other ivars __weak GameMenuLayer *_pop ...
- linux服务搭建----ftp与ftp yum源搭建
ftp服务 如果没有ftp yum -y install vsftpd (前提是你在有yum源的情况下才可以使用这条命令) service vsftpd resta ...
- Android服务器——TomCat服务器的搭建
Android服务器--TomCat服务器的搭建 作为一个开发人员,当然是需要自己调试一些程序的,这个时候本地的服务器就十分方便了,一般都会使用TomCat或者IIS服务器,IIS就比较简单了,其实t ...
- Mybatis源码之RoutingStatementHandler
/** * @author Clinton Begin */ public class RoutingStatementHandler implements StatementHandler { pr ...