在首次啓動容器的時候,必然會進入CreateBean,所以這裏直接採用DeBUG的方式追蹤源碼。
啓動Spring容器之前在方法上打上斷點。
調試出來自己認識的Bean
step into
創建Bean的主要做以下幾件事情。
- Bean類型的解析
- 處理方法的覆蓋
- Bean實例化之前的後置處理
- doCreateBean
到下一步
獲取這個Bean的BeanDefiniton實例
獲取這個BeanDefinition對用的Bean的class對象 ,驗證需要重寫的方法。
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
如果Bean配置了前置或者後置處理器,則進入相關邏輯的處理。
@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) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
如果配置後置 處理器,那麼就會直接返回經過後置處理包裝的Bean.
如果沒有配置,則會進入自己創建的邏輯。
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//這個 方法就是解析Bean創建錢的和創建後的後置處理器。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
try {
//自己創建Bean實例的方法。
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
doCreateBean的具體邏輯如下 :
1.通過事先配置好 的工廠方法 ,創建一個沒有屬性值的Bean實例。
2.通過BeanDefinition的 後置處理器來處理Bean的屬性,其中就包括記錄@Autowired和@Value的屬性。
3.是否允許提前暴露。(即是單例模式,允許將還沒有給屬性賦值的Bean給暴露在外。)
4.填充屬性(自動注入)
5.初始化操作 。
6.視情況註冊銷燬邏輯。
7.返回創建好的實例 。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 定義了一個Bean的包裝類,可以獲取修改Bean的屬性
BeanWrapper instanceWrapper = null;
//是單例
if (mbd.isSingleton()) {
//從包裝類緩存中嘗試獲取,
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//如果沒有獲取到,就自行創建包裝類
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//從包裝類中獲取Bean實例
final Object bean = instanceWrapper.getWrappedInstance();
//從包裝類中獲取Bean類型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//對自動注入和@value的屬性做處理
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
//是否允許提前暴露
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");
}
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.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}