spring IOC:DefaultSingletonBeanRegistry

 

 

spring IOC:DefaultSingletonBeanRegistry

http://whoknow.javaeye.com/blog/487786

假设你遇到的问题是做一个IOC容器,如何开始?
Java代码 复制代码
  1. public   interface  BeanFactory {   
  2.   
  3.     String FACTORY_BEAN_PREFIX =  "&" ;   
  4.   
  5.     Object getBean(String name)  throws  BeansException;   
  6.   
  7.     Object getBean(String name, Class requiredType)  throws  BeansException;   
  8.   
  9.      boolean  containsBean(String name);   
  10.   
  11.      boolean  isSingleton(String name)  throws  NoSuchBeanDefinitionException;   
  12.   
  13.     Class getType(String name)  throws  NoSuchBeanDefinitionException;   
  14.   
  15.     String[] getAliases(String name);   
  16. }  
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);
}


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

一个类一个责任:

这是一条很简单的设计原则,但很难把握
Spring中的IOC容器设计,由 BeanFactory提供一个基本的描述,然后由其它接口描述其主要组件的功能,再由具体的子类逐层实现。每个类都有很清晰的责任,这样做复用性很好,而且阅读起来结构非常的清晰

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

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

3个Map,其中singletonCache,disposableBeans是LinkedHashMap, dependentBeanMap只是普通的map。
Java代码 复制代码
  1. private   final  Map singletonCache    
  2. private   final  Map disposableBeans   
  3. private   final  Map dependentBeanMap =  new  HashMap();  
private final Map singletonCache 
private final Map disposableBeans
private final Map dependentBeanMap = new HashMap();


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

首先想看的就是spring是如何保存一个bean的。
在这个registerSingleton方法中,我们只是将类放入到了一个Map中,而Bean的创建是由其子类完成的。
如同它的名字registerSingleton只负责Bean的注册(保存到Map中)和Bean的销毁(从map中移除,并调用其相应的destory()方法
Java代码 复制代码
  1. // 注册一个实体类   
  2. public   void  registerSingleton(String beanName, Object sharedBean)    
  3.          //先判断是否存在,然后在添加,即把类放入singletonCache这个map中   
  4. Object oldObject =  this .singletonCache.get(beanName);   
  5.              if  (oldObject !=  null ) {…}   
  6.         addSingleton(beanName, sharedBean);   
  7.     }   
  8.   
  9. //如果一个bean,它的产生依赖其它类,那么会使用这个方法,同样依赖类会被放入到dependentBeanMap中   
  10. public   void  registerDependentBean(String beanName, String dependentBeanName)   
// 注册一个实体类
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) 


spring中bean的生命周期经历了很多阶段,DispposableBean接口实现的是Bean的销毁过程,如果Bean实现了该接口,将会在创建过程中进行注册
Java代码 复制代码
  1. // 将BeanName放入disposableBeans这个Map中   
  2. public   void  registerDependentBean(String beanName, String dependentBeanName)       
  3.            
  4. // 得到一个类有2种方法直接从map中取出或由一个工厂类提供(考虑到工厂产生类的情况)   
  5. public  Object getSingleton(String beanName) {   
  6.   
  7. public  Object getSingleton(String beanName, ObjectFactory singletonFactory)   
// 将BeanName放入disposableBeans这个Map中
public void registerDependentBean(String beanName, String dependentBeanName)    
		
// 得到一个类有2种方法直接从map中取出或由一个工厂类提供(考虑到工厂产生类的情况)
public Object getSingleton(String beanName) {

public Object getSingleton(String beanName, ObjectFactory singletonFactory) 


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

Java代码 复制代码
  1. public   void  destroySingleton(String beanName) {   
  2.          //从map中将bean移除   
  3.         removeSingleton(beanName);   
  4.   
  5.          //移除相关的DisposableBean实例   
  6.         DisposableBean disposableBean =  null ;   
  7.          synchronized  ( this .disposableBeans) {   
  8.             disposableBean = (DisposableBean)  this .disposableBeans.remove(beanName);   
  9.         }   
  10.         destroyBean(beanName, disposableBean);   
  11.     }   
  12.   
  13.   
  14.      protected   void  destroyBean(String beanName, DisposableBean bean) {   
  15.         Set dependencies =  null ;   
  16.          synchronized  ( this .dependentBeanMap) {   
  17.           //在这里寻找是否有依赖类,然后调用destroySingleton方法   
  18.             dependencies = (Set)  this .dependentBeanMap.remove(beanName);   
  19.         }   
  20.   
  21.          if  (dependencies !=  null ) {   
  22.              if  (logger.isDebugEnabled()) {   
  23.                 logger.debug( "Retrieved dependent beans for bean '"  + beanName +  "': "  + dependencies);   
  24.             }   
  25.              for  (Iterator it = dependencies.iterator(); it.hasNext();) {   
  26.                 String dependentBeanName = (String) it.next();   
  27.                 destroySingleton(dependentBeanName);   
  28.             }   
  29.         }   
  30.   
  31.          if  (bean !=  null ) {   
  32.              try  {   
  33.                 bean.destroy();   
  34.             }   
  35.              catch  (Throwable ex) {   
  36.                 logger.error( "Destroy method on bean with name '"  + beanName +  "' threw an exception" , ex);   
  37.             }   
  38.         }   
  39.     }   
  40.   
  41. }  
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);
			}
		}
	}

}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值