写在前面:趁着寒假尾声整理了一波上学期自己的Java源码笔记总结,把一篇篇小笔记总结成文章,系统性的转到博客,这样的年度总结希望能对同好们有帮助
1.单例模式理解
确保某一个类只有一个实例,而且提供全局访问点实例化并向整个系统提供这个实例,这个类称为单例类(Spring提供的访问点是beanFactory)
2.单例模式的要点有三个
一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。
3.ErrorContext的单例实现代码:
//具有一个static的局部instance变量和一个获取instance变量的方法
public class ErrorContext {
//有趣的地方是,LOCAL的静态实例变量使用了ThreadLocal修饰,也就是说它属于每个线程各自的数据
private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<ErrorContext>();
//构造函数是private修饰
private ErrorContext() {
}
//而在instance()方法中,先获取本线程的该实例,如果没有就创建该线程独有的ErrorContext
public static ErrorContext instance() {
ErrorContext context = LOCAL.get();
if (context == null) {
context = new ErrorContext();
LOCAL.set(context);
}
return context;
}
2.getSingleton一路跟踪下去,发现实际上是调用了 AbstractAutowireCapableBeanFactory 的 doCreateBean 方法,返回了BeanWrapper包装并创建的bean实例。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从缓存singletonObjects(实际上是一个map)中获取bean实例
Object singletonObject = this.singletonObjects.get(beanName);
//如果为null,对缓存singletonObjects加锁,然后再从缓存中获取bean,如果继续为null,就创建一个bean。
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
//双重判断加锁
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//通过 singletonFactory.getObject() 返回具体beanName对应的ObjectFactory来创建bean。
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
} } }