spring IOC:DefaultSingletonBeanRegistry

假设你遇到的问题是做一个IOC容器,如何开始?
[code]
public interface BeanFactory {

String FACTORY_BEAN_PREFIX = "&";

Object getBean(String name) throws BeansException;

Object getBean(String name, Class requiredType) throws BeansException;

boolean containsBean(String name);

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

Class getType(String name) throws NoSuchBeanDefinitionException;

String[] getAliases(String name);
}
[/code]

BeanFactory是spring与容器交互最基本的一个描述,即我们需要从容器中得到一个实体类,判断它是否存在,是否是单例,又或是它的类型是什么样的。

一个类一个责任:

这是一条很简单的设计原则,但很难把握
Spring中的IOC容器设计,由 BeanFactory提供一个基本的描述,然后由其它接口描述其主要组件的功能,再由具体的子类逐层实现。每个类都有很清晰的责任,这样做复用性很好,而且阅读起来结构非常的清晰
[img]http://whoknow.iteye.com/upload/picture/pic/47039/766b6cea-8f02-34fb-8d19-ec6b922c25fd.jpg[/img]

我们从上至下,先看一下DefaultSingletonBeanRegistry这个类

SingletonBeanRegistry接口描述了对Bean一系列的操作
DefaultSingletonBeanRegistry是它的实现类

3个Map,其中singletonCache,disposableBeans是LinkedHashMap, dependentBeanMap只是普通的map。
[code]
private final Map singletonCache
private final Map disposableBeans
private final Map dependentBeanMap = new HashMap();
[/code]

[b]LinkedHashMap(详见Think in Java)[/b]
LinkedHashMap散列化所有的元素,但是在遍历“键值对”时,却又以元素的插入顺序返回“键值对”(println()会迭代遍历该映射,由此可以看到遍历的结果)。此外,可以在构造器中设定LinkedHashMap,使之采用给予访问的“最近最少使用”(LRU)算法,于是没有被访问过的(可以看作需要删除的)元素就会出现在队列的前面。对于需要定期清理元素以节省空间的程序来说,此功能使得程序很容易得以实现。

首先想看的就是spring是如何保存一个bean的。
在这个registerSingleton方法中,我们只是将类放入到了一个Map中,而Bean的创建是由其子类完成的。
如同它的名字registerSingleton只负责Bean的注册(保存到Map中)和Bean的销毁(从map中移除,并调用其相应的destory()方法
[code]
// 注册一个实体类
public void registerSingleton(String beanName, Object sharedBean)
//先判断是否存在,然后在添加,即把类放入singletonCache这个map中
Object oldObject = this.singletonCache.get(beanName);
if (oldObject != null) {…}
addSingleton(beanName, sharedBean);
}

//如果一个bean,它的产生依赖其它类,那么会使用这个方法,同样依赖类会被放入到dependentBeanMap中
public void registerDependentBean(String beanName, String dependentBeanName)
[/code]

spring中bean的生命周期经历了很多阶段,DispposableBean接口实现的是Bean的销毁过程,如果Bean实现了该接口,将会在创建过程中进行注册
[code]
// 将BeanName放入disposableBeans这个Map中
public void registerDependentBean(String beanName, String dependentBeanName)

// 得到一个类有2种方法直接从map中取出或由一个工厂类提供(考虑到工厂产生类的情况)
public Object getSingleton(String beanName) {

public Object getSingleton(String beanName, ObjectFactory singletonFactory)
[/code]

最后,从容器中移除,destroySingleton,destroyBean两个方法递归调用,即不但要销毁这个bean,其对应的DisposableBean,调用destory()方法。而且如果这个类有依赖类,那么还要继续搜索,销毁其依赖类

[code]
public void destroySingleton(String beanName) {
//从map中将bean移除
removeSingleton(beanName);

//移除相关的DisposableBean实例
DisposableBean disposableBean = null;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}


protected void destroyBean(String beanName, DisposableBean bean) {
Set dependencies = null;
synchronized (this.dependentBeanMap) {
//在这里寻找是否有依赖类,然后调用destroySingleton方法
dependencies = (Set) this.dependentBeanMap.remove(beanName);
}

if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (Iterator it = dependencies.iterator(); it.hasNext();) {
String dependentBeanName = (String) it.next();
destroySingleton(dependentBeanName);
}
}

if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
}

}
[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值