面试真题--------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入门第一季》之面向对象接口面试题
首先,(1)叙述接口的成员特点: /* 接口成员特点 成员变量:只能是常量,默认都是常量,并且是静态的. 默认修饰符:public static final 建议:自己手动给出类似:public st ...
- Swift基础之UIImageView(都是2.2版本)
//设置全局变量,将下面的替换即可 //var myImgView = UIImageView(); //系统生成的viewDidLoad()方法 override func ...
- 网站开发进阶(二十六)js刷新页面方法大全
js刷新页面方法大全 在项目开发过程中,需要实现刷新页面.经过学习,发现下面这条语句就可以轻松实现. location.reload(); // 刷新页面 有关刷新页面的其它方法,具体学习内容如下,有 ...
- SVM实验
说明: 1)α2=0表示第二个样例不在分类面上,在分类面上的点αi均不为零. 2)二次项矩阵,可以通过矩阵相乘相加方法得到,如上例 3)目标函数变为负值,是为了照顾matlab的标准型. 假定应用多项 ...
- 《java入门第一季》之面向对象面试题(形式参数的问题)
/* 形式参数的问题: 基本类型:形式参数的改变不影响实际参数 引用类型:形式参数的改变直接影响实际参数 */ //形式参数是基本类型 class Demo { public int sum(int ...
- 关于精灵帧(Sprite Frame)的尺寸大小
一个对象的精灵帧(Sprite Frame)有若干关于大小的尺寸. 比较容易混淆,这里记录下来区别: CCSpriteFrame *spriteFrame = self.spriteFrame; CG ...
- EBS form 之间跳转实现(form 关闭)
实现 form CUXOMWB 使用 app_navigate.execute 打开 form CUXOEXPRAVA :然后 FROM CUXOEXPRAVA 上点击按钮 跳回from CUXOMW ...
- SQL Queries and Multi-Org Architecture in Release 12
In this Document Abstract History Details Previous Releases Release 12 Multi-Org Session ...
- android.os.NetworkOnMainThreadException异常如何解决
android.os.NetworkOnMainThreadException 08-08 17:53:30.635 I/ArticleTable(22461): 添加成功 58 08-08 17:5 ...
- OS X 平台的 8 个实用终端工具
本文由 伯乐在线 - shinancao 翻译自 mitchchn.欢迎加入iOS小组.转载请参见文章末尾处的要求. OS X 终端对外开放了许多很强大的UNIX实用工具和脚本.如果你是从Linux转 ...