Spring源码之bean的加载(四)获取单例
来源:互联网 发布:线割编程招聘 编辑:程序博客网 时间:2024/04/25 03:03
前面我们有讲过Spring是如何去获取单例的bean,获取是从缓存中来的,可是要是缓存中没有的话怎么办?Spring中使用了getSingleton的方法来重新加载。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)
下面是getSingleton的主要代码。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "'beanName' must not be null");synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while the singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<Exception>();}try {singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// Has the singleton object implicitly appeared in the meantime ->// if yes, proceed with it since the exception indicates that state.singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}afterSingletonCreation(beanName);}if (newSingleton) {addSingleton(beanName, singletonObject);}}return (singletonObject != NULL_OBJECT ? singletonObject : null);}}
上述代码中其实是使用了回调的方法,使得程序可以在单例创建的前后做一些准备及处理操作,而真正获取单例bean的方法其实并不是在此方法中实现,其实实现逻辑是在ObjectFactory类型的实例sinfletonFactory中实现。而这些准备及处理操作包括如下内容:
1) 检查缓存是否已经加载过
2) 若没有加载,则记录beanName的正在加载状态
3) 加载单例前记录加载状态
protected void beforeSingletonCreation(String beanName) {if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}}
4) 通过调用参数传入的ObjectFactory的个体Object方法实例化bean。
5) 加载单例后的处理方法调用
protected void afterSingletonCreation(String beanName) {if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");}}
6) 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}
7) 返回结果处理。
if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}
0 0
- Spring源码之bean的加载(四)获取单例
- Spring源码之bean的加载(二)获取单例bean
- Spring源码(四)-bean的加载(上)
- Spring源码之bean的加载(三)从bean中获取对象
- Spring源码之bean的加载(一)
- Spring源码解析之Bean的加载
- Spring源码之bean的加载(五)准备创建bean
- spring源码深度解析(笔记四)--bean的加载
- spring源码阅读之Bean的加载(一)
- spring源码阅读之Bean的加载(二)
- Spring源码分析之Bean的加载流程
- bean的加载(五)获取单例
- 单例java类获取spring的bean方法
- SPRING源码分析(四)之@Configuration @Bean的方式配置bean
- spring源码初步学习-bean的加载
- Spring源码解析-bean的加载
- Spring源码(五)-bean的加载(下)
- Spring缓存中获取单例bean
- Spring源码之bean的加载(二)获取单例bean
- Spring源码之bean的加载(三)从bean中获取对象
- 解决DRM找不到的问题。
- Facebook Phone Interview -- Move Zeros to Right (Easy)
- 嵌入式编程基础知识学习(1)
- Spring源码之bean的加载(四)获取单例
- 并查集
- Spring源码之bean的加载(五)准备创建bean
- 【杭电oj】2277 - Change the ball(找规律)
- Using multiple LLVM versions on Ubuntu
- 【BZOJ 4443】 [Scoi2015]小凸玩矩阵|二分|最大匹配|匈牙利
- Java命名规范及给自己写的方法添加注解
- 【BZOJ 4448】 [Scoi2015]情报传递|树链剖分|树套树
- spring初步和struts2整合