finishBeanFactoryInitialization(beanFactory)
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 判斷beanFactory是否有CONVERSION_SERVICE_BEAN_NAME的實作,如果有的話設定屬性。為上下文初始化類型轉換器。
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 檢查上下文中是否存在類型轉換器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
//标記正在執行個體化當中,禁止對 bean 的定義再修改。
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 進行單例bean的執行個體化
beanFactory.preInstantiateSingletons();
}
- beanFactory.freezeConfiguration();标志正在執行個體化當中,同時,記錄正在執行個體化的beanDefinition的名字。
- beanFactory.preInstantiateSingletons();執行個體化單例bean。

進入preInstantiateSingletons()方法
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
//周遊一個副本以允許init方法,而init方法反過來注冊新的bean定義。
//盛放所有的beanName,所有的需要執行個體化的beanName都在這裡,包括Spring斷斷續續添加的, Aspectj的, 程式員通過注解辨別的
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//合并父類BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//三個條件,抽象,單例,非懶加載,符合條件再進行加載
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//檢驗是否是 FactoryBean 類型的對象,如果是則加上&再調用getBean(beanName),如果不是則直接調用。
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
- 擷取所有的beanNames,然後周遊判斷是否符合執行個體化的條件。
- 合并父 beanDefinition 與子 beanDefinition,判斷這個bean是否是 非抽象、非懶加載的單例bean,是的話進入執行個體化。
- 執行個體化首先判斷是否為FactoryBean,FactoryBean 适用于 Bean 的建立過程比較複雜的場景。FactoryBean 的話,在 beanName 前面加上 ‘&’ 符号。再調用 getBean()。對FactoryBean而言,這個Bean不是簡單的Bean,而是一個能生産或者修飾對象生成的工廠Bean,它的實作與設計模式中的工廠模式和修飾器模式類似 。
- 調用getBean();
進入getBean(beanName)方法
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
進入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
*/
getBean 方法是我們經常用來擷取 bean 的,但它也同時封裝了初始化的過程,已經初始化過了就從容器中直接傳回,否則就先初始化再傳回
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// getBean 方法是我們經常用來擷取 bean 的,但它也同時封裝了初始化的過程,已經初始化過了就從容器中直接傳回,否則就先初始化再傳回
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 擷取一個 “正統的” beanName,處理兩種情況,一個是前面說的 FactoryBean(前面帶 ‘&’),
// 一個是别名問題,因為這個方法是 getBean,擷取 Bean 用的,你要是傳一個别名進來,是完全可以的
final String beanName = transformedBeanName(name);
// 這個是傳回值
Object bean;
// 檢查下是不是已經建立過了
Object sharedInstance = getSingleton(beanName);
// if 内部是擷取 bean 的邏輯。
// 這裡說下 args,前面我們一路進來的時候都是 getBean(beanName),是以 args 傳參其實是 null 的,
// 但是如果 args 不為空的時候,那麼意味着調用方不是希望擷取 Bean,而是建立 Bean
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 + "'");
}
}
// 下面這個方法,如果是普通 Bean 的話,直接傳回 sharedInstance,如果是 FactoryBean 的話,傳回它建立的那個執行個體對象。
// 如果對 FactoryBean 不熟悉,附錄中有介紹。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// else 内部是初始化 bean 的邏輯
else {
// 目前 beanName 的 prototype 類型的 bean 正在被建立則抛異常
// 往往是因為陷入了循環引用。prototype 類型的 bean 的循環引用是沒法被解決的。這跟 Java 裡面的一樣,會導緻棧溢出。
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
// 檢查一下這個 BeanDefinition 在容器中是否存在
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果目前容器不存在這個 BeanDefinition,試試父容器中有沒有
String nameToLookup = originalBeanName(name);
// 傳回父容器的查詢結果
if (parentBeanFactory instanceof AbstractBeanFactory) {
// Delegation to parent with explicit args.
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);
}
}
// typeCheckOnly 為 false,将目前 beanName 放入一個 alreadyCreated 的 Set 集合中
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
/**
* 稍稍總結一下:
* 到這裡的話,要準備建立 Bean 了,對于 singleton 的 Bean 來說,容器中還沒建立過此 Bean;
* 對于 prototype 的 Bean 來說,本來就是要建立一個新的 Bean。
*/
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 先初始化依賴的所有 Bean,注意,這裡的依賴指的是 depends-on 中定義的依賴
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 檢查是不是有循環依賴
// 這裡的依賴還是 depends-on 中定義的依賴
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注冊一下依賴關系
registerDependentBean(dep, beanName);
try {
// 先初始化被依賴項
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 如果是 singleton scope 的,建立 singleton 的執行個體
if (mbd.isSingleton()) {
// 這裡并沒有直接調用 createBean 方法建立 bean 執行個體,而是通過 getSingleton(String, ObjectFactory) 方法擷取 bean 執行個體。
// getSingleton(String, ObjectFactory) 方法會在内部調用 ObjectFactory 的 getObject() 方法建立 bean,并會在建立完成後,
// 将 bean 放入緩存中。
sharedInstance = getSingleton(beanName, () -> {
try {
// 執行建立 Bean,詳情後面再說
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 跟上面的一樣,如果是普通 Bean 的話,直接傳回 sharedInstance,如果是 FactoryBean 的話,傳回它建立的那個執行個體對象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果是 prototype scope 的,建立 prototype 的執行個體
else if (mbd.isPrototype()) {
// prototype 對象每次擷取都會建立新的執行個體
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
// 執行建立 Bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 如果不是 singleton 和 prototype 的話,需要委托給相應的實作類來處理
else {
String scopeName = mbd.getScope();
final 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 {
// 執行建立 Bean
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 最後,檢查一下類型對不對,不對的話就抛異常,對的話就傳回了
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
- 擷取一個 “正統的” beanName,處理兩種情況,一個是前面說的 FactoryBean(前面帶 ‘&’),一個是别名問題,因為這個方法是 getBean,擷取 Bean 用的,你要是傳一個别名進來,是完全可以的。
- getSingleton(beanName),跟進源碼檢視這個方法,重點分析下面這行代碼,這個singletonObjects就是微觀層面的IOC容器,因為我們的getBean()方法存在遞歸調用,通過getSingleton()保證不會重複建立已經存在的執行個體。
- 下面這段代碼完成真正的bean的建立
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);
}
分析createBean()方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
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.
// 做各種各樣的屬性值的指派, 比如這種 通過Spring的Bean傳遞給Spring架構的值 ==> bd.setPropertyValue("aaa")
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 處理 lookup-method 和 replace-method 配置,Spring 将這兩個配置統稱為 override method
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 在執行個體化之前完成一次解析操作,這個方法主要是執行個體化實作了InstantiationAwareBeanPostProcessor的bean的postProcessBeforeInstantiation方法傳回的執行個體。
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);
}
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);
}
}
進入doCreateBean方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// BeanWrapper 是一個基礎接口,由接口名可看出這個接口的實作類用于包裹 bean 執行個體。
// 通過 BeanWrapper 的實作類可以友善的設定/擷取 bean 執行個體的屬性
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 從緩存中擷取 BeanWrapper,并清理相關記錄
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 建立 bean 執行個體,并将執行個體包裹在 BeanWrapper 實作類對象中傳回,之後會細談
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 此處的 bean 可以認為是一個原始的 bean 執行個體,暫未填充屬性
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 涉及接口:MergedBeanDefinitionPostProcessor,用于處理已“合并的 BeanDefinition”,這塊細節就不展開了
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;
}
}
// earlySingletonExposure 是一個重要的變量,用于解決循環依賴,該變量表示是否提前暴露,
// earlySingletonExposure = 單例 && 是否允許循環依賴 && 是否存于建立狀态中
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");
}
// 添加工廠對象到 singletonFactories 緩存中
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 擷取早期 bean 的引用,如果 bean 中的方法被 AOP 切點所比對到,此時 AOP 相關邏輯會介入
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 注冊銷毀邏輯
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
- 從緩存中擷取 BeanWrapper 實作類對象,并清理相關記錄,BeanWrapper 用到了裝飾器模式
- 若未命中緩存,則建立 bean 執行個體,并将執行個體包裹在 BeanWrapper 實作類對象中傳回
- 應用 MergedBeanDefinitionPostProcessor 後置處理器相關邏輯
- 根據條件決定是否提前暴露 bean 的早期引用(early reference),用于處理循環依賴問題
- 調用 populateBean 方法向 bean 執行個體中填充屬性
- 調用 initializeBean 方法完成餘下的初始化工作
-
注冊銷毀邏輯
接下來我們挑 doCreateBean 中的三個細節出來說說。一個是建立 Bean 執行個體的 createBeanInstance 方法,一個是依賴注入的 populateBean 方法,還有就是回調方法 initializeBean。
1. 建立執行個體
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a BeanWrapper for the new instance
* @see #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* @see #instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 檢測這個類的通路權限, Spring預設是 允許通路非public類型的方法
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工廠方法不為空,則通過工廠方法建構 bean 對象。
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 如果不是第一次建立,比如第二次建立 prototype bean。這種情況下,我們可以從第一次建立知道,
// 采用無參構造函數,還是構造函數依賴注入來完成執行個體化。
// 這裡的 resolved 和 mbd.constructorArgumentsResolved 将會在 bean 第一次執行個體化的過程中被設定.
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 通過有參構造器構造 bean 對象
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 通過無參構造器構造 bean 對象
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 判斷是否采用有參構造函數
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 通過有參構造器構造 bean 對象
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 通過無參構造器構造 bean 對象
return instantiateBean(beanName, mbd);
}
- 檢測類的通路權限,若禁止通路,則抛出異常
- 若工廠方法不為空,則通過工廠方法建構 bean 對象,并傳回結果
- 若構造方式已解析過,則走快捷路徑建構 bean 對象,并傳回結果
- 如第三步不滿足,則通過組合條件決定使用哪種方式建構 bean 對象
2.屬性注入
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// bean 執行個體的所有屬性都在這裡了
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
// 到這步的時候,bean 執行個體化完成(通過工廠方法或構造方法),但是還沒開始屬性設值,
// InstantiationAwareBeanPostProcessor 的實作類可以在這裡對 bean 進行狀态設定,比如忽略屬性值的設定
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 如果傳回 false,代表不需要進行後續的屬性設值,也不需要再經過其他的 BeanPostProcessor 的處理
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 通過名字找到所有屬性值,如果是 bean 依賴,先初始化依賴的 bean。記錄依賴關系
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 通過類型裝配。複雜一些
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 這裡有個非常有用的 BeanPostProcessor 進到這裡: AutowiredAnnotationBeanPostProcessor
// 對采用 @Autowired、@Value 注解的依賴進行設值
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 設定 bean 執行個體的屬性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
- 擷取屬性清單 pvs
- 在屬性未注入之前,使用後置處理器進行狀态設定
- 根據名稱或類型解析相關依賴
- 再次應用後置處理,用于實作基于注解的屬性注入
-
将屬性應用到 bean 對象中
第3步,也就是根據名稱或類型解析相關依賴。該邏輯隻會解析依賴,并不會将解析出的依賴立即注入到 bean 對象中。這裡解析出的屬性值是在 applyPropertyValues 方法中統一被注入到 bean 對象中的。我們常用到的注解式屬性注入比較多,是以這裡就看一下基于注解的屬性注入。
2.1基于注解的屬性注入
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 找到要以注解形式注入的屬性資訊
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 開始注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
// 對每個屬性依次注入
element.inject(target, beanName, pvs);
}
}
}
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 要注入的字段
Field field = (Field) this.member;
Object value;
// 會把注入過的屬性緩存起來
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 字段的描述,包括字段名、是否必需、所屬類、注解資訊等
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
// 類型轉換器,用于将 String 類型轉換成其它類型
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 核心,實際解析屬性的地方,傳回的是依賴的執行個體
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
// 通過反射注入
field.set(bean, value);
}
}
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (javaUtilOptionalClass == descriptor.getDependencyType()) {
return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 核心,解析依賴
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 該方法最終調用了 beanFactory.getBean(String, Class),從容器中擷取依賴
Object shortcut = descriptor.resolveShortcut(this);
// 如果容器中存在所需依賴,這裡進行斷路操作,提前結束依賴解析邏輯
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
// 處理 @value 注解
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
// 解析數組、list、map 等類型的依賴
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
/*
* findAutowireCandidates 這個方法邏輯比較複雜,它傳回的是一個<名稱,類型/執行個體>的候選清單。比如下面的配置:
*
* <bean name="mongoDao" class="com.huzb.demo.MongoDao" primary="true"/>
* <bean name="service" class="com.huzb.demo.Service" autowire="byType"/>
* <bean name="mysqlDao" class="com.huzb.demo.MySqlDao"/>
*
* 我們假設這個屬性的類型是 Dao,而 mongoDao 和 mysqlDao 都繼承了 Dao 接口,mongoDao 已被執行個體化,mysqlDao
* 尚未執行個體化,那麼傳回的候選清單就是:
*
* matchingBeans = [ <"mongoDao", [email protected]>, <"mysqlDao", [email protected]> ]
*
* 方法内部的工作流程如下:
* 1. 方法開始時有一個 type 記錄需要的屬性的類型資訊。
* 2. 類型如果是容器對象(我們在容器準備時放進 resolvableDependencies 的),那直接從容器中拿到,加入候選清單。
* 3. 根據類型資訊從 BeanFactory 中擷取某種類型 bean 的名稱清單,比如按上面配置拿到的就是["mongoDao","mysqlDao"]
* 4. 周遊上一步得到的名稱清單,并判斷 bean 名稱對應的 bean 是否是合适的候選項,若是合适,則把執行個體對象(已執行個體化)
* 或類型(未執行個體化)加入候選清單
* 5. 傳回候選清單
*/
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
// 抛出 NoSuchBeanDefinitionException 異常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
/*
* matchingBeans.size() > 1,則表明存在多個可注入的候選項,這裡判斷使用哪一個候選項。
* 候選項的判定規則是:
* 1)聲明了 primary 的優先級最高
* 2)實作了排序接口,如 Ordered 的優先級比沒實作排序接口的高;同樣實作了排序接口的會通過比較器比較
* 3)還沒有得到結果的話,則按字段名進行比對
*/
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
// 抛出 NoUniqueBeanDefinitionException 異常
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
return null;
}
}
// 根據解析出的 autowiredBeanName,擷取相應的候選項
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else { // 隻有一個候選項,直接取出來即可
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 傳回候選項執行個體,如果執行個體是 Class 類型,則調用 beanFactory.getBean(String, Class) 擷取相應的 bean。否則直接傳回即可
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
- 找到要以注解形式注入的屬性資訊
- 依次對每個字段操作
- 構造字段的描述,包括字段名、是否必需、所屬類、注解資訊等
- 擷取屬性值
- @Value 設定的值,将 String 轉成對應類型後傳回
- 依賴的類型是個數組或集合,會将符合條件的 bean 全部放在數組或集合中傳回
- 普通類型傳回一個候選清單,然後根據判定規則選出優先級最高的一個
- 如果得到的屬性是個 Class 對象,則調用 getBean 生成執行個體
- 通過反射注入
3、處理各種回調
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// 如果 bean 實作了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回調
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessBeforeInitialization 回調
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 處理 bean 中定義的 init-method,
// 或者如果 bean 實作了 InitializingBean 接口,調用 afterPropertiesSet() 方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessAfterInitialization 回調
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
參考資料:
1https://huzb.me/2019/03/04/Spring%E6%BA%90%E7%A0%81%E6%B5%85%E6%9E%90%E2%80%94%E2%80%94bean%20%E5%88%9B%E5%BB%BA%E6%B5%81%E7%A8%8B/#4%E3%80%81getSingleton
2.https://coding.imooc.com/class/404.html