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