设计模式之单例模式
来源:互联网 发布:淘宝宝贝用手机拍照 编辑:程序博客网 时间:2024/06/04 19:07
搞Java编程的时候,经常听人提起单例模式,但我当初并不在意,以为这纯理论我也用不着。今天在撸代码是跟进spring的源码。发现单例模式的应用就在身边呀。
Spring的依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建。lazy-init方式,在容器初始化时候进行调用,非lazy-init方式,在用户向容器第一次索要bean时进行调用。
代码如下:
protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null); }
在这里Spring并没有使用私有构造方法来创建bean,而是通过singletonFactory.getObject()返回具体beanName对应的ObjectFactory来创建bean。实际上是调用了AbstractAutowireCapableBeanFactory的doCreateBean方法,返回了BeanWrapper包装并创建的bean实例。
代码如下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); }....
getEarlyBeanReference获取bean的所有后处理器,并进行处理。如果是SmartInstantiationAwareBeanPostProcessor类型,就进行处理,如果没有相关处理内容,就返回默认的实现。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); if (exposedObject == null) { return exposedObject; } } } } return exposedObject; }
那么何为单例呢,单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式可分为懒汉式和饿汉式:
懒汉式单例类
//懒汉式单例类.在第一次调用的时候实例化 2 public class Singleton { 3 //私有的默认构造子 4 private Singleton() {} 5 //注意,这里没有final 6 private static Singleton single=null; 7 //静态工厂方法 8 public synchronized static Singleton getInstance() { 9 if (single == null) { 10 single = new Singleton();11 } 12 return single;13 }14 }
//饿汉式单例类.在类初始化时,已经自行实例化 2 public class Singleton { 3 //私有的默认构造子 4 private Singleton() {} 5 //已经自行实例化 6 private static final Singleton single = new Singleton(); 7 //静态工厂方法 8 public static Singleton getInstance() { 9 return single;10 }11 }
1 0
- 设计模式之 单例设计模式
- 设计模式之 单例设计模式
- 设计模式之单例设计模式
- 设计模式之-----------单例设计模式
- 设计模式之:单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之-单例设计模式
- 设计模式之单例设计模式 标签: 设计模式
- 设计模式之单例
- 设计模式之单例
- 设计模式之 单例
- Java的设计思想之值对象
- CI框架中163邮箱发送邮件
- linux测验一 知识点
- android布局----RelativeLayout
- nested exception is com.fasterxml.jackson.databind.JsonMappingException: Conflicting getter definiti
- 设计模式之单例模式
- MySQL主从复制
- eclipse-代码之美快捷键
- switch case 避免bug
- cglib动态代理技术
- winform和webform有什么区别
- 腾讯优图实现人脸对比
- redis 配置启动
- PyGobject(二十三)布局容器之AspectFrame