天天看點

Spring 源碼之--getBean完整流程

begin with : new AnnotationConfigApplicationContext(MainConfig.class);

==> org.springframework.context.annotation.AnnotationConfigApplicationContext 

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses)

--> refresh(); 

==> org.springframework.context.support.AbstractApplicationContext

public void refresh() throws BeansException, IllegalStateException 

--> finishBeanFactoryInitialization(beanFactory);

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)

--> beanFactory.preInstantiateSingletons();

==>org.springframework.beans.factory.support.AbstractBeanFactory

public void preInstantiateSingletons() throws BeansException

-->this.getBean(beanName);

public Object getBean(String name) throws BeansException

-->return doGetBean(name, null, null, false);

傳入的參數:

String name, bean的名稱(可能是别名)

final Class<T> requiredType, 需要從容器中擷取的類型

final Object[] args, 傳入的構造器參數,通過這個參數指定具體使用哪個構造器

boolean typeCheckOnly 辨別目前bean是不是作檢查标記

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly)

--> final String beanName = transformedBeanName(name);

傳入的名稱可能是别名,在這裡作别名解析

-->Object sharedInstance = getSingleton(beanName);

去緩存中擷取對象(三級緩存)

singletonObjects 單例緩存池,用于儲存建立完成的對象

第一步:先去單例緩存池中擷取,看是否有建立好的對象,有直接傳回對象.

第二步:在單例緩存池singletonObjects中沒有找到對象, 且singletonsCurrentlyInCreation标記了目前bean是否正在建立,從map裡面去找,找到了就說明正在建立

第三步:去二級緩存earlySingletonObjects 中擷取,若沒有擷取到,就要去三級緩存中擷取

第四步:singletonFactories 去三級緩存中擷取,那麼什麼時候放入到容器中的了?

在調用CreateBeanInstance 之後,populateBean之前放進去的.(以ObjectFactory形式放進去的)

==> if sharedInstance is null ==> 

-->bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

建立的對象可能不是我們想要的也有可能是FactoryBean,在這裡我們需要處理工廠bean

判斷目前bean是不是工廠bean如果是這裡直接傳回

-->return bean

==>else 

-->BeanFactory parentBeanFactory = getParentBeanFactory();

擷取父工廠

-->containsBeanDefinition(beanName)

父容器不為空,目前的容器又沒有包含該bean,有且一種情況就是default

這裡的邏輯分支就是,目前容器有父容器,且目前容器不包含目前bean定義,那麼就會走父容器建立bean的流程

-->final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

合并Bean的定義,存在父bean是一個抽象bean,專門用來給子bean做繼承的

-->checkMergedBeanDefinition(mbd, beanName, args);

校驗目前的bean定義,若目前的bean定義是abstract的話直接抛出異常

-->registerDependentBean(dep, beanName);

解析依賴的bean,并且注冊依賴,

比如InstancA建立該對象 必須要依賴InstanceB的話,那麼就會首先建立B對象

sharedInstance = getSingleton(beanName, () -> {}

if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
	try {
		return createBean(beanName, mbd, args);
	}
	catch (BeansException ex) {
		// Explicitly remove instance from singleton cache: It might have been put there
		// eagerly by the creation process, to allow for circular reference resolution.
		// Also remove any beans that received a temporary reference to the bean.
		destroySingleton(beanName);
		throw ex;
	}
	});
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
           

根據Bean定義的scope來建立Bean

==>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)

beforeSingletonCreation(beanName);

辨別目前建立對象放入到一個辨別singletonsCurrentlyInCreation對象中

singletonObject = singletonFactory.getObject();

通過ObjeccFacotry.getObject()方法觸發createBean的流程, 如上的匿名類中的createBean()

return createBean(beanName, mbd, args);

==>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

就是在這裡給後置處理器一個機會來傳回代理對象,但是在這裡并沒有建立代理

對象,僅僅是把切面資訊解析出來緩存好

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)

instanceWrapper = createBeanInstance(beanName, mbd, args);

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

return instantiateUsingFactoryMethod(beanName, mbd, args);

通過工廠方法來建立Bean執行個體 @Bean的形式配置的

return autowireConstructor(beanName, mbd, null, null);

在構造函數上辨別了@Autowired的注入方法 調用構造方法來建立

return instantiateBean(beanName, mbd);

調用無參的構造器來建立對象

@componet @Service 。。。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

把剛剛建立好的對象 屬性還沒有指派的對象通過ObjectFactory的形式加入到緩存中,用來解決循環依賴

/**
 * Add the given singleton factory for building the specified singleton
 * if necessary.
 * <p>To be called for eager registration of singletons, e.g. to be able to
 * resolve circular references.
 * @param beanName the name of the bean
 * @param singletonFactory the factory for the singleton object
 */
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(singletonFactory, "Singleton factory must not be null");
	synchronized (this.singletonObjects) {
		if (!this.singletonObjects.containsKey(beanName)) {
			this.singletonFactories.put(beanName, singletonFactory);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
}
           

populateBean(beanName, mbd, instanceWrapper);

給建立對象的屬性指派

exposedObject = initializeBean(beanName, exposedObject, mbd);

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)

invokeAwareMethods(beanName, bean);

回調XXXAware接口

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

調用後置處理啊的before方法

invokeInitMethods(beanName, wrappedBean, mbd);

調用init方法

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

調用後置處理器的after方法

 ==>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)

afterSingletonCreation(beanName);

目前的bean已經建立好了 把目前的bean給從singletonsCurrentlyInCreation移除掉

addSingleton(beanName, singletonObject);

把建立好的對象放進到緩存池,情況二三級緩存

/**
 * Add the given singleton object to the singleton cache of this factory.
 * <p>To be called for eager registration of singletons.
 * @param beanName the name of the bean
 * @param singletonObject the singleton object
 */
protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		this.singletonObjects.put(beanName, singletonObject);
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}
           

==>org.springframework.beans.factory.support.AbstractBeanFactory

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,

      @Nullable final Object[] args, boolean typeCheckOnly)

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

建立的對象可能不是我們想要的也有可能是FactoryBean,在這裡我們需要處理工廠bean

return bean

繼續閱讀