(http://blog.csdn.net/weiythi/article/details/74194083)
控制反转——spring通过一种称作控制反转(IoC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
部分参考资料:《控制反转(IoC)与依赖注入(DI)》 博主写的不错,简单易懂。
以上这一段摘自[《Spring源码分析(一)-Spring环境的初始化》]
Spring实现IOC和DI的最主要的核心就是BeanFactory了
BeanFactory
BeanFactory实际上是实例化,配置和管理众多bean的容器。 这些bean通常会彼此合作,因而它们之间会产生依赖。 BeanFactory使用的配置数据可以反映这些依赖关系中 (一些依赖可能不像配置数据一样可见,而是在运行期作为bean之间程序交互的函数)。
一个BeanFactory可以用接口org.springframework.beans.factory.BeanFactory表示, 这个接口有多个实现。 最常使用的的简单的BeanFactory实现是org.springframework.beans.factory.support.DefaultListableBeanFactory
(这里注意一下,好多文章说的是:org.springframework.beans.factory.xml.XmlBeanFactory
)这个类已经被(@deprecated as of Spring 3.1 in favor of {@link DefaultListableBeanFactory})
通过查看DefaultListableBeanFactory的类图,我们可以看到其庞大的类家族,这里有几个分支。
1.BeanFactory
2.BeanDefinitonRegistry
3.SingletonBeanRegistry
其中BeanDefinitonRegistry在之前的文章中已有少数说明,BeanFactory位于类结构树的顶端,其主要的方法就是getBean,即通过BeanName获取到由BeanFactory管理的Bean实例
BeanFactory的功能通过其子接口得到不断的扩展,其主要的几个
- ListableBeanFactory:定义了访问容器中bean的基本信息的若干方法,如查看bean的个数,获取某一类型bean的配置名称,或者查看容器中是否包含某一bean等等这些方法。
- HierarhicalBeanFactory:父子级联IoC容器的接口,子容器可以通过接口方法访问父容器。
- ConfigurableBeanFactory:增强了IoC容器的可定制性。他定义了设置类装载器、属性编辑器、容器初始化后置处理器等等方法。
- AutowireCapableBeanFactory:将容器中的bean按照某种规则比如:按照名称匹配,按照类型匹配等等来进行自动装配的方法。
- SingletonBeanFactory:在容器运行期间向容器注册单实例bean的方法
- BeanDefinitionRegistry:Spring配置文件中,每一个bean节点元素在Spring容器里面都通过一个BeanDefinition对象来表示,他描述了Bean的配置信息。BeanDefinitionRegistry接口提供了向容器手工注册BeanDefinition对象的方法。
BeanFactory 的方法定义(markdown贴html代码片好像做不到,截个图吧):
有的时候在线文档更简单易懂,还能离IDE的线,自行学习。其实看其定义的方法,通过其方法的描述很容易看懂其功能,BeanFactory定义的若干方法中,出现最多的既是getBean,可见BeanFactory的主要功能都是围绕Bean展开的,是否有Bean,获得Bean的别名,根据名称获取bean,根据类型获取bean,bean是多例的还是单例的。
那么BeanFactory的实现类是如何维护Bean的呢,刚刚说道最常用的BeanFactory的实现就是DefaultListableBeanFactory,如果想先了解Bean是如何被取出的,那么需要先知道Bean是如何被注册到容器中的,还好我们之前已经通过几篇文章分析了Spring解析bean定义的流程,其最后是通过以下代码完成注册的。
/**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
//使用工具类注册Bean
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
BeanDefinitionReaderUtils.registerBeanDefinition 源码如下
/**
* Register the given bean definition with the given bean factory.
* @param definitionHolder the bean definition including name and aliases
* @param registry the bean factory to register with
* @throws BeanDefinitionStoreException if registration failed
*/
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
// 获取beanName
String beanName = definitionHolder.getBeanName();
// 注册Bean的定义
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 注册BeanName对应的别名
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
我们通过之前贴出的UML图和以前的文章,可知DefaultListableBeanFactory本身就是一个BeanDefinitionRegistry,如ctrl+alt+b图所示:
根据《Spring源码阅读之-bean的解析与注册》 中得出的总结,注册到BeanFactory中的是一个BeanDefinition对象,暂且不去探究其代码层面上是如何维护BeanDefinition的(想想看,beanName需要对应BeanDefinition,类内部维护这样的关系肯定是一个Map结构),但是注册BeanDefinition只是AbstractApplicationContext类中refresh执行的众多操作的一环,其在registerBeanDefinition方法中并没有对对象做初始化的操作,那么什么时候做的呢?