Spring IoC 中的(Singleton)單例對象創建過程探索


前言

  之前將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);
	}

  

總結

  上述內容記錄的很少,基本就是一個輪廓的記錄,要真正理解詳情內容,還得自己去慢慢調試啊!!!

  

 

  

 
        

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM