Spring IOC容器分析(1) -- BeanFactory
搭建好源码阅读环境后,就可以慢慢走进Spring殿堂了。IOC是Inversion of Control的缩写,控制反转的意思。很多人可能都知道IOC是spring的核心,将对象的创建初始化等权限交由容器控制,从而减少对象之间的依赖。甚至听说过BeanFactory,知道BeanFactory是实现IOC机制的核心,但是具体如何实现,却不是十分清楚。下面我们来一步一步深入理解BeanFactory。
引例
在spring工程应用中,一般用spring注解@Autowired来自动加载依赖对象,如下所示:
public class MerchantController {
@Autowired
private final MerchantService merchantService;
}
注解@Autowired使得对象加载很方便,使得对象依赖间管理很容易。但是依据守恒定律,对象的加载、创建、初始化等步骤是不会减少的,这里使用简单了,那必然在别的地方执行了对象的加载、创建、初始化的过程。实际上这个加载、创建、初始化的过程是在Spring源码BeanFactory中完成的。
BeanFactory
首先看下BeanFactory源码,BeanFactory是一个祖宗级接口,定义了Bean Factory的各种基本方法。spring中各种具体bean工厂均是对BeanFactory接口的实现,如DefaultListableBeanFactory,SimpleJndiBeanFactory,StaticListableBeanFactory等。
作为一个接口,BeanFactory定义的方法非常简单,而且都是一些常用的方法模板,如:getBean(),containsBean(),isSingleton()方法。BeanFactory接口如下:
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
顾名思义,getBean()方法是用来获取Bean工厂中存储的对象实例,根据name即可获得对应的对象,也即是配置文件(暂认为xml)中定义的id。containsBean是用于判断该Bean工厂中是否含有name所对应的对象。isSingleton是判断该name所对应的Bean是否是共享的单例,如果true的话,当调用getBean()方法时便会返回该Bean。
由getBean()方法,应该能够猜测出:Bean工厂是先将name-bean作为一个键值对存储在一个容器中,当调用getBean()方法时,根据key值取出对应的bean值。实际上,spring中的确是这么做的。
根据UML类图关系,找到BeanFactory接口对应的默认实现类DefaultListableBeanFactory,如下图所示。

查看DefaultListableBeanFactory源码,发现:属性中beanDefinitionMap用于存储name-bean键值对,也即是存放Bean工厂实例化后的bean。截取部分源码如下:
package org.springframework.beans.factory.support;
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
............
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
...........
}
从源码可以发现,存储键值对的容器是ConcurrentHashMap,它是一个基于HashMap的高并发容器,具有很好的线程安全性。其存储的不是String-Object键值对,而是String-BeanDefinition键值对,也就是说创建的bean对象不是以Object类型存储的,而是Bean Definition类型存储。为什么是这样的呢?请听下回分解
Spring IOC容器分析(1) -- BeanFactory的更多相关文章
- Spring IOC容器分析(2) -- BeanDefinition
上文对Spring IOC容器的核心BeanFactory接口分析发现:在默认Bean工厂DefaultListableBeanFactory中对象不是以Object形成存储,而是以BeanDefin ...
- Spring IOC容器分析(4) -- bean创建获取完整流程
上节探讨了Spring IOC容器中getBean方法,下面我们将自行编写测试用例,深入跟踪分析bean对象创建过程. 测试环境创建 测试示例代码如下: package org.springframe ...
- Spring IOC容器分析(3) -- DefaultListableBeanFactory
上一节介绍了封装bean对象的BeanDefinition接口.从前面小结对BeanFactory的介绍中,我们知道bean对象是存储在map中,通过调用getBean方法可以得到bean对象.在接口 ...
- Spring IoC容器的设计——BeanFactory应用场景
1.BeanFactory提供的是最基本的IoC容器的功能,关于这些功能定义,我们可以在接口BeanFatory中看到. 2.BeanFactory接口定义了IoC容器最基本的容器的形式,并且提供了I ...
- Spring IoC容器的设计——BeanFactory应用场景2
1.BeanFactory接口设计了getBean方法,这个方法是使用IoC容器API的主要方法,通过这个方法,可以取得IoC容器中管理的Bean,Bean的取得是通过指定名字来索引的. 2.如果需要 ...
- spring揭密学习笔记(3)-spring ioc容器:Spring的IoC容器之BeanFactory
1. Spring的IoC容器和IoC Service Provider的关系 Spring的IoC容器和IoC Service Provider所提供的服务之间存在一定的交集,二者的关系如图4-1所 ...
- Spring Ioc容器核心类继承图
Spring IOC容器其实就是BeanFactory的实例,Spring中BeanFactory的类关系结构如下图: 从上图可以看出Beanfactory作为根接口又细化出三个二级接口,最后又有Co ...
- Spring源码分析:Spring IOC容器初始化
概述: Spring 对于Java 开发来说,以及算得上非常基础并且核心的框架了,在有一定开发经验后,阅读源码能更好的提高我们的编码能力并且让我们对其更加理解.俗话说知己知彼,百战不殆.当你对Spri ...
- 【spring源码分析】spring ioc容器之前生今世--DefaultListableBeanFactory源码解读
spring Ioc容器的实现,从根源上是beanfactory,但真正可以作为一个可以独立使用的ioc容器还是DefaultListableBeanFactory,因此可以这么说, DefaultL ...
随机推荐
- IO模型分析
html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...
- The area 积分积分
The area Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Sta ...
- handlebar JS模板使用笔记
直接上代码: (定义模板) (编译注入) ***知识点*** //数据必须为Json数据(强调:jsonp数据不行,和json是两种数据,jsonp多了callback回调函数来包裹json数据) 遍 ...
- The model backing has changed
其他信息: The model backing the 'WebTopFormContext' context has changed since the database was created. ...
- Log4j按级别输出日志到不同文件配置分析 (转:projava)
关于LOG4J 按照级别输出日志,并按照级别输出到不同文件中的说法有很多, 网上贴的最多的log4j.properties的设置是这样的 log4j.rootLogger=info,stdout,in ...
- git-分支使用方式
需求场景:假如你看着教程完成了一个项目,但是感觉第一次代码掌握不牢,想要进行第二次代码练习--如果某某心里想我还有初始备份文件,我此时的心里独白是你的硬盘还够用吗o(╯□╰)o 1 创建一个新分支 - ...
- dotweb框架之旅 [一] - HelloWorld
一直想着,要系统性的写一些dotweb使用的文章,之前拖延了不少时间,今天,下定决定,算是正式的开始,也请大家一起监督. dotweb,是一款追求简约大方的go web框架,正如其github项目主页 ...
- css百分比参照大总结
最近做PC端项目,由于要自适应到800*600,所以免不了要使用百分比的布局方式,但是一开始有点搞不清楚百分比的参照,于是页面的布局怎么调也调不好. 事后我进行了一下总结,希望能够帮到大家: 参照父元 ...
- java连接sqlserver2008r2 心得
现在是该轻松一笑的时候了,困扰已久的问题有了解释了. 之前的各种连不上,说到底还是权限问题,sqlserver2008r2的权限分得太细了. 两个实例间数据库互相都看不到,更不用谈访问了. 端口号也是 ...
- ASP.NET没有魔法——ASP.NET MVC是如何运行的?它的生命周期是什么?
前面的文章我们使用ASP.NET MVC创建了个博客应用,那么它是如何工作的呢?我们都知道ASP.NET的程序需要部署到IIS上才能够通过浏览器来访问,那么IIS与ASP.NET MVC程序之间又是如 ...