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 ...
随机推荐
- 混合高斯模型(Mixtures of Gaussians)和EM算法
这篇讨论使用期望最大化算法(Expectation-Maximization)来进行密度估计(density estimation). 与k-means一样,给定的训练样本是,我们将隐含类别标签用表示 ...
- tcpip第三章
1,ip协议不可靠.无连接特性介绍 不可靠:计算机A往计算机B发送数据报1,若途径的路由器缓存已满,或者ttl(time to live 生存周期)到了,则路由器直接丢弃数据包1,并产生icmp数据包 ...
- Chrome Extension in CLJS —— 搭建开发环境
前言 磨刀不误砍柴工,本篇将介绍如何搭建Chrome插件的ClojureScript开发环境. 具体工具栈:vim(paredit,tslime,vim-clojure-static,vim-fir ...
- C#中回车出发事件(+收藏)
本文给大家介绍如何在c# winform中实现回车事件和回车键触发按钮的完美写法 我们常常要在c# winform中实现回车(enter)提交功能,这样比手动按按钮触发更快. 要完成回车按按钮功能,只 ...
- 关于如何获取iframe中的元素
今天研究了一下iframe中元素的获取,发现有些地方还是有点坑的. 首先:如果使用纯前端手段,是没有办法获取非同源的iframe中的元素的,后面会提到后端手段 一.同源环境 1.首先在父页面获取ifr ...
- Python-MongoDB的驱动安装、升级
安装pip,并通过此来安装pymongo–Python mongodb驱动 1.下载pip安装包,下载地址:http://pypi.python.org/packages/source/p/pip/p ...
- Java面向对象 继承(上)
Java面向对象 继承 知识概要: (1)继承的概述 (2)继承的特点 (3)super关键字 (4)函数覆盖 (5) 子类的实例化过程 (6) final关键字 (1)继承 ...
- 第四章 MySQL高级查询(二)
第四章 MySQL高级查询(二) 一.EXISTS子查询 在执行create 或drop语句之前,可以使用exists语句判断该数据库对像是否存在,返回值是true或false.除此之外,exists ...
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) D. Sorting the Coins
http://codeforces.com/contest/876/problem/D 题意: 最开始有一串全部由"O"组成的字符串,现在给出n个数字,指的是每次把位置n上的&qu ...
- SAP问题【转载】
1.A:在公司代码分配折旧表时报错? 在公司代码分配折旧表时报错,提示是"3000 的公司代码分录不完全-参见长文本" 希望各位大侠帮我看看. 3000 的公司代码分录不完全-参见 ...