前言
之前將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); }
總結
上述內容記錄的很少,基本就是一個輪廓的記錄,要真正理解詳情內容,還得自己去慢慢除錯啊!!!