概述
spring創建bean時需要一個重要的對象,那就是BeanDefinition對象,spring在創建BeanFactory時會把xml配置文件和註解信息轉換爲一個個BeanDefinition對象,BeanDefinition對象存儲的是單個bean的配置信息,比如依賴類、scope、是否延遲加載等等,對於BeanDefinition的創建過程,可以閱讀我的Spring4.3.x 淺析xml配置的解析過程系列,如
把<bean>標籤轉換成BeanDefinition對象
解析context命名空間之annotation-config標籤
解析context命名空間之component-scan標籤
解析aop命名空間之config標籤
解析aop命名空間之aspectj-autoproxy標籤
拿到BeanDefinition對象和一切準備工作完成後,Spring就開始根據BeanDefinition對象創建第一的bean。那Spring容器是怎麼創建bean的呢?這就是這篇文章討論的內容。
在spring容器的初始化過程中,BeanFactory對象創建完成後,容器就會創建並執行bean工廠後處理器對象,然後在註冊Bean後處理器時會創建Bean後處理器對象,初始化消息資源時會創建MessageSource對象,初始化事件傳播器時會創建ApplicationEventMulticaster對象。前面所有應用內部級的對象創建完成後,容器纔會初始化所有業務級的非延遲加載單例對象。關於spring容器的初始化過程見Spring4.3.x 容器的刷新過程,下面從spring容器創建非延遲加載單例對象來探討bean的創建過程。
創建bean的過程
Spring容器在刷新過程中以AbstractApplicationContext的finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)方法爲初始化容器中所有非延遲加載單例bean的入口,這個方法的源碼如下。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化ConversionService
// 在ConfigurableApplicationContext接口中聲明:String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
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));
}
// 註冊一個默認的內部value解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// 初始化LoadTimeWeaverAware對象來支持註冊他們的transformers
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用臨時類加載器來做類型匹配
beanFactory.setTempClassLoader(null);
// 允許緩存所有的bean元數據定義,不希望今後再更改工廠的配置
beanFactory.freezeConfiguration();
// 初始化所有非延遲單例bean
beanFactory.preInstantiateSingletons();
}
finishBeanFactoryInitialization方法中創建bean的代碼是最後一句,調用ConfigurableListableBeanFactory接口的preInstantiateSingletons()方法,這個方法的實現代碼在DefaultListableBeanFactory類中,源碼如下。
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 複製一份Bean名稱
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 觸發所有非延遲加載單例bean的初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 獲取FactoryBean對象
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit; // 標識FactoryBean是否需要馬上初始化Bean
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 創建Bean
getBean(beanName);
}
} else {
// 創建Bean
getBean(beanName);
}
}
}
for (String beanName : beanNames) {
// 獲取指定的Bean,此步驟會使用BeanFacotry對象獲取對應的Bean
Object singletonInstance = getSingleton(beanName);
// 觸發所有SmartInitializingSingleton對象的afterSingletonsInstantiated()方法
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
preInstantiateSingletons()方法調用BeanFactory接口的getBean(String name)方法來創建Bean,此方法的實現代碼在AbstractBeanFacotry中,源碼如下。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
這裏簡單說一下BeanFactory的5個getBean重載方法的實現最終都是調用AbstractBeanFacotry類的doGetBean方法,它有4個參數,第一個參數爲字符串類型的name參數,可以是bean的ID或者別名;第二個參數爲Class類型的requiredType參數,指定需要獲取的Bean的類型;第三個參數爲Object數組的args參數,用於指定構造方法的參數;第四個參數爲布爾類型的typeCheckOnly,true表示只做類型檢查,false不僅要檢查類型,還要把bean標識爲已創建。這個方法的源碼如下。
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// 首先從singleton緩存中查找手動註冊的單例對象
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 返回sharedInstance自身
// 如果sharedInstance爲FactoryBean對象,則返回它所創建的Bean實例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 檢查beanName是否指向的是一個正在創建的prototype對象,是則拋出異常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 檢查當前BeanFacotry中是否存在對應的BeanDefintion對象
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 不存在,則從父BeanFactory中獲取Bean
String nameToLookup = originalBeanName(name);
if (args != null) {
// 根據指定的構造器參數創建Bean
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// 把bean標識爲已創建
markBeanAsCreated(beanName);
}
try {
// 獲取RootBeanDefinition對象
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 檢查BeanDefintion是否合格,如果它代表的是一個抽象類,則拋出異常
checkMergedBeanDefinition(mbd, beanName, args);
// 獲取bean所依賴的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 初始化所有依賴的Bean
for (String dependsOnBean : dependsOn) {
if (isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
}
registerDependentBean(dependsOnBean, beanName);
getBean(dependsOnBean);
}
}
// 創建Bean實例
if (mbd.isSingleton()) {
// 創建單例bean
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 創建Bean
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// bean爲prototype,創建新的實例
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
// 創建bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 創建其它作用域的Bean
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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;
}
}
// 檢查創建好的Bean實例的類型是否與requiredType匹配
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
// 如果不匹配則進行類型轉換
return getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type [" +
ClassUtils.getQualifiedName(requiredType) + "]", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
在doGetBean方法中,不管是哪種作用域的Bean,都會調用createBean方法來創建Bean實例,createBean方法在AbstractBeanFactory中被定義爲抽象方法,它的實現在AbstractAutowireCapableBeanFactory類中,源碼如下。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 從bean的定義中獲取正確的Class對象
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// 準備方法重寫,這個是通過<lookup-method>標籤定義的
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 執行InstantiationAwareBeanPostProcessor的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);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
AbstractAutowireCapableBeanFactoryd的createBean會調用resolveBeforeInstantiation方法來執行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,如果這個方法返回的bean不爲null,則bean創建完成。否則將調用看AbstractAutowireCapableBeanFactory類的doCreateBean方法創建bean的,doCreateBean方法的源碼如下。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// 初始化bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 創建Bean實例,並返回其包裝器
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// 到這一步,Bean已經實例化完成,但還沒定製bean的屬性
// 此時,執行MergedBeanDefinitionPostProcessor對象的postProcessMergedBeanDefinition方法
// 比如處理@Autowired、@Value等註解
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// 爲了解決bean之間的循環引用,需要提前緩存單例的Bean的引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 爲單例bean添加ObjectFactory對象
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 此處將執行SmartInstantiationAwareBeanPostProcessor後處理器的getEarlyBeanReference方法
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// 初始化bean的
Object exposedObject = bean;
try {
// 設置bean的屬性值
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 調用bean後處理器以及InitializingBean的afterPropertiesSet方法
// =>和init-method方法
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) {
// 獲得單例bean
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<String>(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 {
// 如果bean需要在工廠關閉前被銷燬,則註冊bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean方法是實例化和初始化bean的戰場,它調用createBeanInstance方法創建bean的實例和BeanWrapper對象;調用populateBean方法設置bean的屬性;調用initializeBean方法執行Bean後處理器和InitializingBean對象的afterPropertiesSet方法以及init-method方法;最後調用registerDisposableBeanIfNecessary方法註冊bean的銷燬方法。
總結
(1)不管是什麼作用域的bean,都會通過AbstractAutowireCapableBeanFactory類的doCreateBean方法來創建。doCreateBean方法是創建bean的主要戰場。
(2)只要調用BeanFactory對象的任意一個getBean方法都會觸發bean的創建,BeanFactory接口提供了5個getBean重載方法。