面试真题--------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源 ...
随机推荐
- SVM实验
说明: 1)α2=0表示第二个样例不在分类面上,在分类面上的点αi均不为零. 2)二次项矩阵,可以通过矩阵相乘相加方法得到,如上例 3)目标函数变为负值,是为了照顾matlab的标准型. 假定应用多项 ...
- ubuntu下搭建gtk+编程环境
首先gtk+项目主页为: http://www.gtk.org/ gtk+现在有2和3两种版本,使用 sudo apt-get install gnome-core-devel 可以一次性安装2个版本 ...
- Zeromq自连接错误
Zeromq自连接错误(金庆的专栏)Zeromq消息中间件开发的服务器和客户端不必按顺序启动,客户端可以在服务器开启之前启动.这是Zmq特别好用的一大特性.利用该特性,网游各功能服务器可以任意重启,实 ...
- ZooKeeper leader election
Paxos是分布式应用中解决同步问题的核心.作为应用研发工程师,我们总是倾向于使用一种相对简洁的方式实现复杂的算法.ZooKeeper leader election实现就是一个非常好的参考. 其实现 ...
- SharePoint 搜索爬网第三方网站配置
介绍:SharePoint的搜索着实强大,而且最近用到SharePoint搜索第三方爬网,感觉收获挺大,而且网上资料没找到太多类似的,就小记录一下,分享给大家. 首先,我自己写了一个net页面,里面读 ...
- 鹅厂优文|打通小程序音视频和webRTC
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯视频云终端技术总监常青, 2008 年毕业加入腾讯,一直从事客户端研发相关工作,先后参与过 PC QQ.手机QQ.QQ物联 等产品 ...
- index() checkbox单选问题
index() 只对兄弟节点有用 如果这种结构要选择checkbox 时用prop附加属性 removeAttr清楚属性 $('.checkbox').prop('checked',true) $(' ...
- Python中导入第三方声源库Acoular的逻辑解释以及Acoular的下载
[声明]欢迎转载,但请保留文章原始出处→_→ 秦学苦练:http://www.cnblogs.com/Qinstudy/ 文章来源:http://www.cnblogs.com/Qinstudy/p/ ...
- Python__flask初识
1. debug:在app.run()里面加上app.run(debug=True), 在浏览器中调试的时候可以直接显示出错误. 2. 在url中传递参数,可以这样 @app.route('/ch ...
- IT轮子系列(六)——Excel上传与解析,一套代码解决所有Excel业务上传,你Get到了吗
前言 在日常开发当中,excel的上传与解析是很常见的.根据业务不同,解析的数据模型也都不一样.不同的数据模型也就需要不同的校验逻辑,这往往需要写多套的代码进行字段的检验,如必填项,数据格式.为了避免 ...