天天看點

Spring bean的擷取、建立過程,生命周期,循環依賴

目錄

      • getSingleton() 擷取單例對象
        • 3個map(三級緩存)
        • 其它集合類型的成員字段
        • getSingleton() 從三級緩存擷取單例bean執行個體
        • getSingleton() 從工廠執行個體擷取單例bean執行個體
      • getBean() 擷取bean執行個體的過程
        • getBean()
        • doGetBean()
        • getBean() 整體流程圖
      • DependsOn依賴
      • bean的懶加載
      • createBean() 建立bean執行個體的過程
        • createBean()
        • createBean() 流程圖
        • doCreateBean()
        • populateBean() 填充屬性,注入所需依賴
        • initializeBean() 初始化
        • doCreateBean() 整體流程圖
      • 循環依賴
        • 循環依賴的概念
        • 循環依賴問題觸發的時機
        • spring解決循環依賴的原理圖
        • spring解決循環依賴的原理
        • spring可以解決哪些種類的循環依賴問題
        • 三級緩存各自的存入時機
        • 可以不要第二級緩存嗎
        • 可以不要第三級緩存嗎 | 隻使用兩級緩存行嗎
      • bean的生命周期
        • bean的生命周期
        • bean生命周期中的常見單詞
        • bean的初始化、銷毀方法
        • @PostConstruct、@PreDestroy
        • bean的後置處理器BeanPostProcessor
        • InstantiationAwareBeanPostProcessor
        • BeanFactoryPostProcessor

使用的spring源碼版本 5.3.x

getSingleton() 擷取單例對象

提供單例操作的類主要是 DefaultSingletonBeanRegistry ,此處介紹這個類的

  • 幾個集合類型的成員變量:三級緩存
  • 2個重載的 getSingleton() 方法:用于擷取單例bean的執行個體
    • getSingleton(String beanName, boolean allowEarlyReferenc) 從三級緩存擷取單例bean的執行個體
    • getSingleton(String beanName, ObjectFactory<?> singletonFactory) 從工廠執行個體擷取單例bean的執行個體

3個map(三級緩存)

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
           

spring使用三級緩存解決循環依賴問題

  • singletonObjects:一級緩存,用于儲存已經建立好的單例bean
  • earlySingletonObjects:二級緩存,用于儲存已經建立執行個體但尚未進行屬性注入(初始化)的單例bean
  • singletonFactories:三級緩存,用于儲存bean的工廠執行個體,二級緩存中存儲的就是從工廠執行個體中擷取到的對象。

其它集合類型的成員字段

/** Set of registered singletons, containing the bean names in registration order. */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

/** Names of beans that are currently in creation. */
private final Set<String> singletonsCurrentlyInCreation =
		Collections.newSetFromMap(new ConcurrentHashMap<>(16));

/** Names of beans currently excluded from in creation checks. */
private final Set<String> inCreationCheckExclusions =
		Collections.newSetFromMap(new ConcurrentHashMap<>(16));


/** Disposable bean instances: bean name to disposable instance. */
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

/** Map between dependent bean names: bean name to Set of dependent bean names. */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
           

getSingleton() 從三級緩存擷取單例bean執行個體

此實質是到三級緩存中嘗試擷取bean

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	//先在一級緩存中查找
	Object singletonObject = this.singletonObjects.get(beanName);
	//如果找不到且目前bean是正在建立的單例bean
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		//則到二級緩存中查找
		singletonObject = this.earlySingletonObjects.get(beanName);
		/**如果二級緩存中也沒有,且 allowEarlyReference為true,則嘗試到三級緩存中擷取對應的工廠執行個體,通過工廠建立bean執行個體,放到二級緩存中并傳回該執行個體(尚未填充屬性)*/
		if (singletonObject == null && allowEarlyReference) {
			/**在此期間,可能其它線程已經建立好了執行個體放到一二級緩存中,是以需要再次校驗一級緩存、二級緩存中是否有對應執行個體,為防止多線程同時操作,加上同步鎖*/
			synchronized (this.singletonObjects) {
				singletonObject = this.singletonObjects.get(beanName);
				//如果一級緩存中仍然沒有
				if (singletonObject == null) {
					singletonObject = this.earlySingletonObjects.get(beanName);
					//二級緩存中也沒有
					if (singletonObject == null) {
						//則從三級緩存中擷取對應的工廠執行個體
						ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
						if (singletonFactory != null) {
							//使用工廠建立bean的執行個體(尚未注入屬性|初始化)
							singletonObject = singletonFactory.getObject();
							//并将建立好的bean執行個體放到二級緩存中
							this.earlySingletonObjects.put(beanName, singletonObject);
							//因為是擷取的是單例bean,三級緩存中對應的工廠執行個體隻會使用一次,是以使用完就可以移除
							this.singletonFactories.remove(beanName);
						}
					}
				}
			}
		}
	}
	//傳回擷取的單例對象
	return singletonObject;
}
           
Spring bean的擷取、建立過程,生命周期,循環依賴

getSingleton() 從工廠執行個體擷取單例bean執行個體

getSingleton(String beanName, ObjectFactory<?> singletonFactory)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	/** 從工廠執行個體擷取單例bean的執行個體,操作之前需要加同步鎖,并校驗緩存中有沒有需要的單例  */
	synchronized (this.singletonObjects) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				/** 從工廠執行個體擷取單例bean的執行個體。
					形參singletonFactory是ObjectFactory的執行個體,ObjectFactory是函數式接口,需要實作getObject()方法。
					ObjectFactory用于從工廠擷取對象執行個體,不僅僅隻用于擷取單例,可能建立的要求是代理,還要注入所依賴的bean,是以實作往往是調用createBean()方法,而非直接調用上面簡單的getSingleton()。
				   在createBean()方法中,bean經過執行個體化、填充屬性、初始化等流程,已經是完全體的bean執行個體了,如果是單例,會被放到二級緩存中。 */
				singletonObject = singletonFactory.getObject();
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// Has the singleton object implicitly appeared in the meantime ->
				// if yes, proceed with it since the exception indicates that state.
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw ex;
				}
			}
			catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			}
			finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				afterSingletonCreation(beanName);
			}
			/** 如果是新建立的單例,則調用addSingleton()方法把,把執行個體放到一級緩存中,并從二三級緩存移除相關執行個體 */
			if (newSingleton) {
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}


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);
	}
}
           

這個方法主要做了2件事

  • 調用工廠執行個體的getObject()方法擷取bean執行個體
  • 如果是新建立的單例,還會把執行個體一級緩存中、從二三級緩存移除對應的執行個體

getBean() 擷取bean執行個體的過程

抽象類 AbstractBeanFactory 包含了許多操作bean的方法,比如

  • 抽象方法 getBeanDefinition()、createBean()
  • 提供了實作的方法 getBean()、 doGetBean()

getBean()

@Override
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
	return doGetBean(name, requiredType, null, false);
}

@Override
public Object getBean(String name, Object... args) throws BeansException {
	return doGetBean(name, null, args, false);
}

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 * @param name the name of the bean to retrieve
 * @param requiredType the required type of the bean to retrieve
 * @param args arguments to use when creating a bean instance using explicit arguments
 * (only applied when creating a new instance as opposed to retrieving an existing one)
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
		throws BeansException {

	return doGetBean(name, requiredType, args, false);
}
           

getBean()實質是調用 doGetBean()

doGetBean()

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 * @param name the name of the bean to retrieve
 * @param requiredType the required type of the bean to retrieve
 * @param args arguments to use when creating a bean instance using explicit arguments
 * (only applied when creating a new instance as opposed to retrieving an existing one)
 * @param typeCheckOnly whether the instance is obtained for a type check,
 * not for actual use
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
		String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

	//轉換别名。如果傳入的是别名,會先轉換為對應的beanName
	String beanName = transformedBeanName(name);
	Object beanInstance;

	//先嘗試從三級緩存中擷取執行個體
	
	//實際是調用 getSingleton(beanName, true)
	Object sharedInstance = getSingleton(beanName);
	//如果從緩存中擷取到執行個體。方法參數args隻用在建立新執行個體時,==null說明是要從緩存中擷取
	if (sharedInstance != null && args == null) {
		if (logger.isTraceEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		//則對執行個體進行修飾處理
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	//如果未擷取到執行個體,說明需要建立執行個體
	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		/** 如果目前BeanFactory執行個體中沒有對應的bean definition,且父BeanFactory執行個體存在,則通過父BeanFactory執行個體擷取bean執行個體。
		   注意:目前類是AbstractBeanFactory,目前對象是BeanFactory的執行個體 */
		
		// Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		/** 執行到此,說明目前BeanFactory執行個體中存在對應的bean definition,那就使用目前BeanFactory執行個體建立bean執行個體 */
		
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
				.tag("beanName", name);
		try {
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}
			//合并bean definition
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			/** 處理DependsOn依賴,如果DependsOn依賴尚未執行個體化,則先執行個體化 */
			
			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					registerDependentBean(dep, beanName);
					try {
						//調用getBean(),保證DependsOn依賴在目前bean執行個體化化之前都已執行個體化
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			/** 開始建立bean執行個體。
				單例、原型建立執行個體的方式有所差別,需要先判斷bean的類型,但核心都是調用createBean()方法建立執行個體。
				此處單例使用的getSingleton()是重載方法,不是操作三級緩存的那個getSingleton() */
				
			// Create bean instance.
			if (mbd.isSingleton()) {
				/** 這個是重載的getSingleton(),從工廠執行個體擷取單例,用lambda表達式實作ObjectFactory接口。
					getSingleton()先調用reateBean()建立bean執行個體,完全建立好的單例放在二級緩存中,getSingleton()再把二級緩存中的這個單例移到一級緩存中 */
				sharedInstance = getSingleton(beanName, () -> {
					try {
						//調用createBean()建立執行個體
						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.
						//createBean()過程中出問題時需要銷毀執行個體,原型每次都是建立,即使出問題也不影響下次getBean(),是以不用銷毀,gc會自動回收
						destroySingleton(beanName);
						throw ex;
					}
				});
				//對執行個體進行修飾處理
				beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					//調用createBean()建立執行個體
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				//對執行個體進行修飾處理
				beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
				String scopeName = mbd.getScope();
				if (!StringUtils.hasLength(scopeName)) {
					throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
				}
				Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);
						}
					});
					//對執行個體進行修飾處理
					beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new ScopeNotActiveException(beanName, scopeName, ex);
				}
			}
		}
		catch (BeansException ex) {
			beanCreation.tag("exception", ex.getClass().toString());
			beanCreation.tag("message", String.valueOf(ex.getMessage()));
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
		finally {
			beanCreation.end();
		}
	}

	return adaptBeanInstance(name, beanInstance, requiredType);
}
           

getBean() 整體流程圖

Spring bean的擷取、建立過程,生命周期,循環依賴

DependsOn依賴

在執行個體化bean之前,會先執行個體化該bean所有的 DependsOn依賴。

如果bean沒有直接使用 | 依賴某些bean,但需要在執行個體化之前保證這些bean已經執行個體化,可以用@DependsOn 或 depends-on 屬性将這些bean辨別為DependsOn依賴。

@Component
@DependsOn("c")  //value指定依賴的bean,String[]形式
class A {

    @Autowired
    private B b;
    
    //...

}
           

bean的懶加載

bean預設都是懶加載的,使用該bean時才進行加載,是以預設流程依次是

  • getBean():BeanFactory的方法,實質是調用doGetBean()
  • doGetBean():依次從單例池(一級緩存)、父容器(父BeanFactory的執行個體)嘗試擷取bean的執行個體,如果未擷取到,則調用createBean()建立bean的執行個體
  • createBean():實質是調用doCreateBean()
  • doCreateBean():建立bean的執行個體

不是直接 createBean() 建立bean的執行個體,而是調用getBean(),用到了該bean的執行個體時才通過createBean()建立執行個體。

可以使用 lazy-init 屬性或 @Lazy 注解設定是否使用懶加載

<!--lazy-init預設true-->
<bean name="" class="" lazy-init="false" />
           
@Component
@Lazy(false)  //value屬性指定是否使用懶加載,預設true
class A {

}
           

createBean() 建立bean執行個體的過程

AbstractAutowireCapableBeanFactory 繼承了 AbstractBeanFactory ,提供多個方法的實作,其中包括 createBean() 方法的實作,主要是調用 doCreateBean() 方法。

這2個類都是抽象類,以下3個方法均是 AbstractAutowireCapableBeanFactory 類中的。

createBean()

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	if (logger.isTraceEnabled()) {
		logger.trace("Creating instance of bean '" + beanName + "'");
	}

	//解析BeanClass
	
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	//準備方法覆寫(校驗BeanDefinition中定義的override方法是否合法)
	// Prepare method overrides.
	try {
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		//給BeanPostProcessor一個傳回代理的機會。spring aop即使用此原理實作
			
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	//調用doCreateBean()建立bean執行個體
	try {
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isTraceEnabled()) {
			logger.trace("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}


/**
 * 執行所有InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法,
 * 如果某個InstantiationAwareBeanPostProcessor接口傳回了代理,則不再執行後續的postProcessBeforeInstantiation()方法,直接執行所有BeanPostProcessor接口的postProcessAfterInitialization()方法。
 * 
 * InstantiationAwareBeanPostProcessor是BeanPostProcessor的一個特殊子接口,用于spring架構内部實作spring aop,
 * 更多資訊可以檢視後面的BeanPostProcessor介紹
 */
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				//執行所有InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				//如果某個InstantiationAwareBeanPostProcessor接口傳回了不為null的對象(代理)
				if (bean != null) {
					//執行所有BeanPostProcessor接口的postProcessAfterInitialization()方法
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}


@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
		Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
		if (result != null) {
			return result;
		}
	}
	return null;
}

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}
           

createBean() 流程圖

Spring bean的擷取、建立過程,生命周期,循環依賴

doCreateBean()

/**
 * @param beanName the name of the bean
 * @param mbd the merged bean definition for the bean
 * @param args explicit arguments to use for constructor or factory method invocation
 * @return a new instance of the bean
 */
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	//執行個體化bean
	// Instantiate the bean.  
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	//合并對bean definition的修改
	// Allow post-processors to modify the merged bean definition. 
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}

	/** 如果允許提前暴露(正在建立的單例 && 允許解決循環依賴),則預加載對應的BeanFactory執行個體到三級緩存中,以便後續解決循環依賴時使用。
		allowCircularReferences是目前類的一個boolean型的成員字段,是否允許自動解決循環依賴,預設true,可以手動設定 */
		
	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		//把對應的BeanFactory執行個體添加到三級緩存中
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		//填充屬性,注入所需依賴
		populateBean(beanName, mbd, instanceWrapper);
		//初始化
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}

	//檢查循環依賴
	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName,
							"Bean with name '" + beanName + "' has been injected into other beans [" +
							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
							"] in its raw version as part of a circular reference, but has eventually been " +
							"wrapped. This means that said other beans do not use the final version of the " +
							"bean. This is often the result of over-eager type matching - consider using " +
							"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}

	/** 注冊bean的銷毀方法。
		包括DisposableBean接口的destroy()方法、destroy-method屬性設定的方法 */
	
	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}
           

populateBean() 填充屬性,注入所需依賴

@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	if (bw == null) {
		if (mbd.hasPropertyValues()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
				return;
			}
		}
	}

	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

	//根據注入模式選擇autowireByName()、autowireByType()進行注入
	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// Add property values based on autowire by name if applicable.
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// Add property values based on autowire by type if applicable.
		if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}

	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

	PropertyDescriptor[] filteredPds = null;
	if (hasInstAwareBpps) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
			if (pvsToUse == null) {
				if (filteredPds == null) {
					filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
				}
				pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					return;
				}
			}
			pvs = pvsToUse;
		}
	}
	if (needsDepCheck) {
		if (filteredPds == null) {
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}


protected void autowireByName(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
		if (containsBean(propertyName)) {
			//getBean()擷取依賴,調用pvs.add()進行注入
			Object bean = getBean(propertyName);
			pvs.add(propertyName, bean);
			registerDependentBean(propertyName, beanName);
			if (logger.isTraceEnabled()) {
				logger.trace("Added autowiring by name from bean name '" + beanName +
						"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
						"' by name: no matching bean found");
			}
		}
	}
}


protected void autowireByType(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}

	Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
		try {
			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
			// Don't try autowiring by type for type Object: never makes sense,
			// even if it technically is a unsatisfied, non-simple property.
			if (Object.class != pd.getPropertyType()) {
				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
				// Do not allow eager init for type matching in case of a prioritized post-processor.
				boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
				DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
				/** 擷取依賴的執行個體,調用pvs.add()進行注入。		
					目前抽象類implements了AutowireCapableBeanFactory接口,但并未實作擷取執行個體的resolveDependency()方法,當然,此方法的實作中也用到了getBean() */
				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
				if (autowiredArgument != null) {
					pvs.add(propertyName, autowiredArgument);
				}
				for (String autowiredBeanName : autowiredBeanNames) {
					registerDependentBean(autowiredBeanName, beanName);
					if (logger.isTraceEnabled()) {
						logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
								propertyName + "' to bean named '" + autowiredBeanName + "'");
					}
				}
				autowiredBeanNames.clear();
			}
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
		}
	}
}
           

此方法主要是根據注入模式,調用autowireByName()或autowireByType()進行注入,這2個方法注入時也會先通過getBean()方法擷取依賴執行個體。

initializeBean() 初始化

/**
 * Initialize the given bean instance, applying factory callbacks
 * as well as init methods and bean post processors.
 * @see BeanNameAware
 * @see BeanClassLoaderAware
 * @see BeanFactoryAware
 * @see #applyBeanPostProcessorsBeforeInitialization
 * @see #invokeInitMethods
 * @see #applyBeanPostProcessorsAfterInitialization
 */
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	//invokeAwareMethods() 處理實作的Aware接口,執行Aware方法
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}

	//applyBeanPostProcessorsBeforeInitialization() 調用所有BeanPostProcessor接口的postProcessBeforeInitialization()方法
	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	//invokeInitMethods() 調用初始化方法	
	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	//applyBeanPostProcessorsAfterInitialization() 調用所有BeanPostProcessor接口的postProcessAfterInitialization()方法
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}


/**
 * 3個Aware接口,依次為:
 * BeanNameAware  setBeanName()  設定beanName
 * BeanClassLoaderAware  setBeanClassLoader()  設定bean的類加載器
 * BeanFactoryAware  setBeanFactory()  設定要使用的工廠執行個體
 */
private void invokeAwareMethods(String beanName, Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		if (bean instanceof BeanClassLoaderAware) {
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}


/**
 * 2個初始化方法,依次為:
 * InitializingBean接口的afterPropertiesSet()方法
 * init-method指定的自定義初始化方法
 */
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
		throws Throwable {

	//執行InitializingBean接口的afterPropertiesSet()方法
	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((InitializingBean) bean).afterPropertiesSet();
					return null;
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
			((InitializingBean) bean).afterPropertiesSet();
		}
	}

	//執行init-method指定的自定義初始化方法
	if (mbd != null && bean.getClass() != NullBean.class) {
		String initMethodName = mbd.getInitMethodName();
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}
           

doCreateBean() 整體流程圖

Spring bean的擷取、建立過程,生命周期,循環依賴

核心流程有3步

  • 建立執行個體
  • 填充屬性、注入依賴
  • 初始化

執行個體化可以看做在堆上建立對象、配置設定記憶體空間,成員字段的值還是預設初始值;填充屬性是給成員字段設定值。

getBean() 擷取bean執行個體過程中,會用到 createBean() 建立執行個體;

createBean() 建立執行個體,populateBean()填充屬性、注入依賴時,也會調用getBean()擷取所需依賴。

DI:其實就是在createBean建立bean執行個體,填充屬性、注入依賴時,使用getBean擷取所需依賴,注入到bean執行個體中。

循環依賴

循環依賴的概念

circular reference,循環引用 | 依賴

bean之間彼此依賴,依賴關系環形閉環
@Component
class A {

    @Autowired
    private B b;

}


@Component
class B {

    @Autowired
    private A a;

}
           
//bean依賴自身也屬于循環依賴

@Component
class A {

    @Autowired
    private A a;

}
           

循環依賴問題觸發的時機

bean執行個體化之後,populateBean()填充屬性時。

spring解決循環依賴的原理圖

A、B構成循環依賴,getBean(beanA)擷取beanA執行個體的過程如下(圖中隻列關鍵步驟)

Spring bean的擷取、建立過程,生命周期,循環依賴

完成後beanA、beanB的執行個體均已在一級緩存中,後續可以從一級緩存中直接擷取。

spring解決循環依賴的原理

核心思想:提前曝光已執行個體化、但尚未完成屬性填充(建立)的執行個體,填充屬性期間可被其它執行個體引用(作為依賴注入)。

執行個體化bean後,會把目前bean對應的工廠執行個體預先加載到三級緩存中;注入依賴、建立所需依賴的執行個體時,可以從三級緩存擷取到目前bean對應的工廠執行個體,通過工廠執行個體可以擷取到之前建立的目前bean的執行個體(已執行個體化但尚未填充屬性),進而完成依賴本身的屬性注入、初始化。

spring可以解決哪些種類的循環依賴問題

  • 單例模式會緩存建立的bean執行個體,原型模式每次都是建立新的執行個體,不會緩存建立的bean執行個體。三級緩存是在getSingleton()擷取單例中使用的,隻能解決單例的循環依賴問題。
  • 均采用setter方法注入,或者一方使用構造方法注入、另一方使用setter方法注入的循環依賴都可以被spring解決。(不能解決全采用構造方法注入的循環依賴)

三級緩存各自的存入時機

  • 放入三級緩存的時機:bean執行個體化之後、填充屬性之前,會把對應的BeanFactory執行個體放到三級緩存中
  • 放入二級緩存的時機:從三級緩存中擷取執行個體時,如果一二級緩存沒有對應的bean執行個體,但三級緩存有對應的工廠執行個體,則通過工廠執行個體的getObject()方法擷取bean執行個體,放到二級緩存中,并移除三級緩存中對應的工廠執行個體
  • 放入一級緩存的時機:執行個體建立完成(完全體)後會被放到一級緩存中,并會移除二三級緩存中對應的執行個體

當spring容器被銷毀時,會銷毀一級緩存中的單例執行個體。

可以不要第二級緩存嗎

二級緩存 earlySingletonObjects,early有2個含義

  • adj. 早期的:早期的單例,已執行個體化但尚未填充屬性、初始化,還不是完全體的單例,不能正常使用,但可以被引用。
  • adv. 提前:本來要成為完全體的單例才暴露出來,二級緩存把已執行個體化的bean提前暴露出來,讓其它bean可以引用。

解決循環依賴主要靠第二級緩存提前暴露早期執行個體,讓其它執行個體可以引用,第二級緩存才是關鍵,不能沒有。

可以不要第三級緩存嗎 | 隻使用兩級緩存行嗎

隻使用一二級緩存時

getBean(beanA) -> 執行個體化beanA ,放到二級緩存中 ->

填充beanA的屬性,getBean(beanB) -> 執行個體化beanB,放到二級緩存中 ->

填充beanB的屬性,getBean(beanA) -> 在二級緩存中擷取到beanA,完成注入 -> beanB建立完成,放到一級緩存中 ->

beanA建立完成,放到一級緩存中

顯然,隻用一二級緩存也可以解決循環依賴問題。

看上面的spring解決循環依賴的原理圖,本來在beanA執行個體化後就可以擷取到引用,把beanA放到二級緩存中;硬是拖了半個流程,在beanB執行個體化後注入依賴,getBean(beanA)時,才從三級緩存中擷取beanA的工廠執行個體,通過工廠擷取beanA執行個體,把beanA執行個體放到二級緩存中。

為什麼要拖那麼久,等beanB填充屬性、注入beanA時才擷取beanA的執行個體放到二級緩存中?因為之前不确定需要的是beanA本身,還是beanA的代理,在beanB實際使用beanA(填充屬性)時才能确定

@Component
class A {

    @Autowired
    private B b;

}
           

使用aop對部分bean中的beanB進行增強,自然要等到建立bean、填充屬性要注入beanB時,才能校驗目前bean是不是目前要注入的依賴(beanB)的目标類(切入點),是就注入beanB的代理,否則注入beanB本身。

工廠執行個體擷取bean執行個體的getObject()方法其實就是:判斷目前bean需要的是依賴本身的執行個體,還是依賴的代理(依賴的代理也屬于依賴的執行個體),需要依賴本身就直接傳回已建立好的依賴執行個體,需要代理就在已建立的依賴執行個體的基礎上進行包裝,傳回代理。

總結

第三級緩存的作用是延緩早期執行個體的暴露時機,把早期執行個體的暴露時機從執行個體化後,推遲到依賴本身的填充屬性、依賴注入時,以便應用spring aop、确定依賴本身是否要注入代理。

如果依賴注入時都沒有使用代理(aop),隻使用一二級緩存也可以解決循環依賴問題。

bean的生命周期

bean的生命周期

一般認為bean的生命周期即執行個體的生命周期,主要邏輯在doCreateBean()方法中,createBean()中解析BeanClass、準備方法覆寫之類的操作不算在bean的生命周期中。

Spring bean的擷取、建立過程,生命周期,循環依賴
  1. 執行個體化
  2. 填充屬性,注入依賴
  3. 如果bean實作了BeanNameAware接口,則調用setBeanName()方法設定beanName
  4. 如果bean實作了BeanClassLoaderAware接口,則調用setBeanClassLoader()方法設定bean的類加載器
  5. 如果bean實作了BeanFactoryAware接口,則調用setBeanFactory()方法 設定要使用的BeanFactory執行個體
  6. 如果bean實作了ApplicationContextAware接口,則調用setApplicationContext()方法設定應用上下文
  7. 如果bean實作了BeanPostProcessor接口,則調用applyBeanPostProcessorsBeforeInitialization() 做初始化的前處理
  8. 如果bean實作了InitializingBean接口,則調用afterPropertiesSet()方法進行初始化
  9. 如果使用了init-method指定的自定義初始化方法,則調用init-method指定的自定義初始化方法
  10. 如果bean實作了BeanPostProcessor接口,則調用postProcessAfterInitialization() 做初始化的後處理

至此,執行個體建立完成,單例模式放到一級緩存中,由spring容器管理,原型模式交給調用者

  • 單例bean的生命周期和spring容器的生命周期保持一緻,在spring容器初始化時就建立執行個體,放到spring容器中,由spring容器負責管理,spring容器運作期間一直存活,在spring容器解除安裝時銷毀執行個體。
  • 原型模式的bean在需要時才建立執行個體,每次都是建立新的執行個體,由spring容器建立執行個體,建立後交給使用方(getBean()的調用者),在沒有任何對象引用時成為垃圾等待gc回收。
  1. 如果bean實作了DisposableBean接口,銷毀時會調用destroy()方法
  2. 如果使用了destroy-method屬性指定銷毀方法,還會調用destroy-method指定的方法

bean生命周期中的常見單詞

  • post:在…之後
  • process:處理、加工
  • processor:處理器、處理程式、加工者
  • BeanPostProcessor:bean後置處理器,對bean進行加工處理
  • aware:意識到的、感覺到的、知道的

bean的初始化、銷毀方法

  • 初始化方法:可以實作InitializingBean接口,在afterPropertiesSet()方法中寫實作,也可以用 init-method 屬性指定。
  • 銷毀方法:常用于釋放 bean 所持有的資源,可以實作DisposableBean接口,在destroy()方法中寫實作,也可以用 destroy-method 屬性指定。

@PostConstruct、@PreDestroy

  • @PostConstruct:在構造方法之後執行,常用于初始化操作
  • @PreDestroy :在對象銷毀之前執行,常用于釋放對象持有的資源
@Component
public class Xxx {

    @PostConstruct
    public void postConstruct() {
        //...
    }

    @PreDestroy
    public void PreDestroy() {
        //...
    }

}
           

jdk自帶的類可分為2類

  • 核心類庫:以java開頭,比如 io、date
  • 擴充類庫:以javax開頭,比如 servlet、swing

這2個注解作用看起來和 init-method、 destroy-method 差不多,但都是 javax 中的注解,不是 spring 的注解,一般不算在 bean 的生命周期中。

bean的後置處理器BeanPostProcessor

bean的後置處理器BeanPostProcessor用于在初始化階段對bean進行加工。

經過建立執行個體、填充屬性2個階段,bean已經建立得差不多了,初始化階段用于對bean進行進一步的加工修飾,xml配置bean的方式(init-method)很少用了,開發主要通過實作BeanPostProcessor接口來對bean做加工處理。

BeanPostProcessor接口有2個預設方法

  • postProcessBeforeInitialization():在bean的初始化方法之前執行
  • postProcessAfterInitialization():在bean的初始化方法之後執行

形參都為執行個體本身、beanName,可根據beanName進行篩選;傳回值是加工後的執行個體;預設實作是不做處理、直接傳回執行個體。

bean可以實作多個BeanPostProcessor接口,實作多個BeanPostProcessor接口時往往還需要實作Ordered接口,通過Ordered接口指定多個BeanPostProcessor的執行順序。

@Component
public class Xxx implements BeanPostProcessor, Ordered {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //...
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //...
        return bean;
    }

    @Override
    public int getOrder() {
        return 0;
    }

}
           

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,沒有重寫BeanPostProcessor的2個預設方法,隻是增加了4個預設方法,其中需要postProcessBeforeInstantiation()方法

@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
	return null;
}
           

在createBean()中,會先給BeanPostProcessor一個傳回代理的機會:執行所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法

  • 如果某個postProcessBeforeInstantiation()方法傳回不為null,則不再執行後續的postProcessBeforeInstantiation()方法,直接執行所有BeanPostProcessor接口的postProcessAfterInitialization()方法,将傳回的對象作為代理直接傳回,不再調用doCreateBean()建立新的執行個體
  • 否則調用doCreateBean()建立新的執行個體

InstantiationAwareBeanPostProcessor是一個特殊的BeanPostProcessor接口,主要在spring架構内部使用,用于spring架構本身實作代理(spring aop)。

spring官方說 InstantiationAwareBeanPostProcessor 是面向spring架構本身|内部的,不推薦開發者使用,盡量用BeanPostProcessor代替。

BeanFactoryPostProcessor

BeanFactoryPostProcessor、BeanPostProcessor都是後置處理器(PostProcessor),用于加工處理,容易混淆,差別如下

  • 加工對象不同:BeanFactoryPostProcessor用于對BeanFactory進行加工處理,BeanPostProcessor用于對Bean進行加工處理
  • 作用時機不同:BeanFactoryPostProcessor作用于spring容器加載bean定義之後、bean執行個體化之前,BeanPostProcessor作用于bean初始化階段。