前言
之前將spring framework 源碼導入了idea,后來折騰調試了一下,於是研究了一下最簡單的singleton對象在spring中是如何創建的。這里所謂的簡單,就是指無屬性注入,無復雜構造函數的對象。
測試代碼
spring配置:
<bean id="userService" class="UserService" scope="singleton"></bean>
測試類:
public class UserService {
private final Log logger = LogFactory.getLog(getClass());
public UserService(){
logger.info("UserService created");
id = UUID.randomUUID().toString();
}
private String id;
public String getId(){
return id;
}
public String getUserName(){
return "xiaopanzi";
}
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
context.start();
testNormalSingleton(context);
}
private static void testCircleSingleton(ClassPathXmlApplicationContext context){
SingletonAService aService = context.getBean("aService",SingletonAService.class);
SingletonBService bService = context.getBean("bService",SingletonBService.class);
aService.getbService().print();
bService.getaService().print();
}
調試詳情
首先在ApplicationContext 初始化過程,在 refresh 方法中會調用 finishBeanFactoryInitialization 方法,注釋上也寫的很明白:Instantiate all remaining (not-lazy-init) signletons。(初始化剩余的非懶加載的單例對象)。那么這里就是入口點。
然后在調用 beanFactory.preInstantiateSingletons().
后續調用鏈如下:
DefaultListBeanFactory.getBean(beanName)
AbstractBeanFactory.doGetBean(name,requiredType,args,typeCheckOnly)
AbstractAutowireCapableBeanFactory.createBean(String beanName,RootBeanDefinition mbd,Object[] args)
AbstractAutowireCapableBeanFactory.doCreateBean(String beanName,RootBeanDefinition mbd,Object[] args)
AbstractAutowireCapableBeanFactory.instantiateBean(final String beanName, final RootBeanDefinition mbd)
getInstantiationStrategy().instantiate(mbd, beanName, parent); (this.instantiationStrategy=CglibSubclassingInstantiationStrategy)
SimpleInstantiationStrategy.instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner)
BeanUtils.instantiateClass(Constructor<T> ctor, Object... args)
通過上述代碼調用鏈我們可以看出,最終的示例創建是由 BeanUtils.instantiateClass 方法完成的,也就是這個方法:

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
到此為止單例就創建完畢了。但是創建完成之后,還有后續的處理。
DefaultSingletonBeanRegistry.addSingletonFactory(String beanName,ObjectFactory<?> singletonFactory);
也就是將該示例放入到 singletonObjects 中,作為緩存方便后續取值。
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
當我們在次調用getBean的時候,那么在 DefaultSingletonBeanRegistry.getSingleton 方法中直接從 singletonObjects 中獲取即可。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
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);
}
總結
上述內容記錄的很少,基本就是一個輪廓的記錄,要真正理解詳情內容,還得自己去慢慢調試啊!!!
