设计模式之单例模式

#小王的学习笔记#

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

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

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

下面是javaBean的获取对象源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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方法获取实例(此处有用到工厂模式),在源码里我们可以看到

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

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

文章目录
|