Spring IOC中的单例模式

#小王的学习笔记#

单例模式可以说是设计模式里最容易理解,解释起来最简单的设计模式了。

特点:这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

他保证了一个类只能有一个实例,并提供一个访问它的全局访问点。

下面是javaBean的获取对象源码

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name 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 singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }

                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }

                this.beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = this.suppressedExceptions == null;
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet();
                }

                try {
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (IllegalStateException var16) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw var16;
                    }
                } catch (BeanCreationException var17) {
                    BeanCreationException ex = var17;
                    if (recordSuppressedExceptions) {
                        Iterator var8 = this.suppressedExceptions.iterator();

                        while(var8.hasNext()) {
                            Exception suppressedException = (Exception)var8.next();
                            ex.addRelatedCause(suppressedException);
                        }
                    }

                    throw ex;
                } finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }

                    this.afterSingletonCreation(beanName);
                }

                if (newSingleton) {
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject;
        }
    }

通过分析javaBean源码可以看到,javaBean运用的就是单例模式获取实例。获取一个对象必须加上同步锁synchronized防止多个线程同步导致的问题(加上锁大家调用这个方法就必须排队等候,类比去公共洗手间)。也就是在ApplicationContext中我们已经初始化了xml文件中所有的bean,并且放入同一块内存区域(可以创建两个bean使用==来测试是否在同一内存),之后由getBean方法获取实例(此处有用到工厂模式),在源码里我们可以看到

private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);

这里储存着所有bean实例,我们添加多个if条件来查询这个hashmap中是否存在这个实例,如果存在就直接map.get()就好了

粤 ICP 备 2020080455 号