BeanFactory的那些事
问:我们知道在Spring应用体系中,我们如果想获得某一个Bean,只需要调用BeanFactory中的getBean()方法即可,那么我们如何获取BeanFactory本身?
答:可以使用转义符“&”来得到FactoryBean本身。
例:BeanFactory是一个FactoryBean,那么使用&BeanFactory得到的是BeanFactory本身,而不是由BeanFactory产生出来的对象(Bean)。
BeanFactory的接口设计
getBean(String name):通过指定名字来索引,获取IoC容器中管理的Bean
getBean(String name,Class
getBean(String name,Object... args):如果需要获取的Bean是prototype类型的,还可以为这个prototype类型的Bean生成指定构造函数的对应参数------(控制生成prototype类型的Bean)
containsBean(String name):让用户能够判断容器是否含有指定名字的Bean。
isSingleton(String name):查询指定名字的Bean是否是singleton类型的Bean。对于singleton属性,用户可以在BeanDefinition中指定。
isPrototype(String name):查询指定名字的Bean是否是prototype类型的Bean。对于prototype属性,用户可以在BeanDefinition中指定。
singleton和prototype的区别:
singleton:当一个Bean的作用域设置为singleton,那么spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例--------换言之-------把一个bean定义设置为singleton作用域时,Spring IOC容器会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例---------->让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用。
prototype:每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例,相当于一个new的操作,对于prototype作用域的bean,Spring不能对该Bean的整个生命周期负责。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。
总结:当你需要全局的唯一标示的时候可以用singleton,而且singleton只创建一个对象,系统消耗资源小.但是用singleton可能会有线程安全化的问题,这个时候就需要用到prototype 。考虑并发的问题,建议都用prototype。
isTypeMatch(String name,Class targetType):查询指定了名字的Bean的Class类型是否是特定的Class类型。这个Class类型可以由用户来指定。
getType(String name):来查询指定名字的Bean的Class类型。
getAliases(String name):来查询指定了名字的Bean的所有别名,这些别名都是用户在BeanDefinition中指定的。
BeanFactory容器的设计原理
BeanFactory接口提供了使用IoC容器的规范。在这基础上,Spring还提供了符合这个IoC容器接口的一系列容器的实现。
例:XmlBeanFactory
XmlBeanFactory设计的类继承关系:
从继承关系中可以看出,XmlBeanFactory与ApplicationContext等应用上下文最大的区别就是,
XmlBeanFactory只提供最基本的IoC容器的功能。
XmlBeanFactory继承自DefaultListableBeanFactory这个类,而在Spring应用中,实际上是把DefaultListableBeanFactory作为一个默认的功能完整的IoC容器来使用。
XmlBeanFactory在继承了DefaultListableBeanFactory容器的功能的同时,增加了对XML进行操作的功能--------可以读取以XML文件方式定义的BeanDefinition的IoC容器。
编程式使用IoC容器:
1、创建IoC配置文件的抽象资源,这个抽象资源包含了BeanDefinition的定义信息。
2、创建一个BeanFactory,这里使用DefaultListableBeanFactory
3、创建一个载入BeanDefinition的读取器,这里使用XmlBeanDefinitionReader来载入XML文件形式的BeanDefinition,通过一个回调配置给BeanFactory。
4、从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成。完成整个载入和注册Bean定义后,需要的IoC容器就建立起来了。这个时候就可以直接使用IoC容器了。