在Spring完成將BeanDefinition
注入IOC容器的任務以後,最主要的一步就是完成對ApplicationContext
中的剩下的全部單例非懶加載Bean
完成預實例化。對於原型Bean
只有使用的時候纔會被建立。java
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
:web
// Instantiate all remaining (non-lazy-init) singletons.
//4.預實例化全部非懶加載的單例Bean
beanFactory.preInstantiateSingletons();
複製代碼
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
:spring
/** * ApplicationContext支持的預實例化 */
@Override
public void preInstantiateSingletons() throws BeansException {
// 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.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
//1.觸發全部非懶加載的單例Bean的初始化
for (String beanName : beanNames) {
//2.合併的BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//3.判斷是否是FactoryBean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
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) {
getBean(beanName);
}
}
else {
//4.主要走這裏
getBean(beanName);
}
}
}
}
複製代碼
上述源碼展現ApplicationContext
預實例化(單例非懶加載)的入口,經過遍歷BeanDefinition
的名稱來獲取Bean
實例。bootstrap
對於singleton bean
,多是FactoryBean
,也多是普通的Bean
,可是從上述的入口能夠看出來,最終都是調用org.springframework.beans.factory.support.AbstractBeanFactory#getBean
來獲取對應bean
實例的,因此主要看該方法。緩存
org.springframework.beans.factory.support.AbstractBeanFactory#getBean
:websocket
/** * 根據beanName獲取bean */
@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);
}
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
複製代碼
getBean
方法提供了幾個重載的方法, 但它自己比較簡單,就是調用了doGetBean
,在Spring中通常doXXX
格式的方法都是真正的作事的方法。session
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
:app
/** * 返回一個實例,能夠是指定Bean的共享實例或獨立實例 */
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
//轉換beanName,爲了解決FactoryBean的&符號
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//1.檢查單例緩存中是否已經存在手動註冊的Bean
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 + "'");
}
}
//若是是普通的bean則直接返回,若是是FactoryBean,則返回FactoryBean所產生的對象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Create bean instance.
//7.單例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//匿名內部類,真實的建立singleton object
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);
}
//8.原型
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//9.其餘的,如:request、session、global session、application、websocket
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
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;
}
}
return (T) bean;
}
複製代碼
這部分源碼只貼了核心的部分,能夠看到,首先會解析beanName
,由於這裏涉及到普通的Bean
和FactoryBean
,爲了解析FactoryBean
的轉義符&
;而後會從IOC的緩存中獲取當前beanName
的實例是否存在,若是存在,則直接返回實例,而後調用getObjectForBeanInstance
方法,若是是Bean
,則直接返回bean
,若是是FactoryBean
,則返回其getObject
返回的對象,這裏也是解決循環引用很重要的一個地方;最後判斷bean
的做用域,根據做用域走不一樣的解決方案,這裏主要看單例。socket
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
:ide
/** * 若是給定的beanName,還沒有註冊,則建立註冊 */
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
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 + "'");
}
//1.添加到正在建立的集合中
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
//2.回調匿名內部類的方法,獲取單例對象
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;
}
//3.從正在建立的集合中移除
afterSingletonCreation(beanName);
}
//4.若是是新單例對象
if (newSingleton) {
//5.添加到單例工廠中進行緩存
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
複製代碼
從這個方法中,能夠看到,首先會從一級緩存中獲取實例,若是不存在,則添加到一個正在建立的集合中,這個也是解決循環引用的一部分;而後調用剛剛傳入的匿名內部類的getObject
方法,建立咱們的實例;最後從正在建立的集合中移除,將新建立的實例放到一級緩存中(singletonObjects
)。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
:
/** * 這個類的核心方法:實現了AbstractBeanFactory的方法 * 負責建立Bean */
@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;
// 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.
//1.解析BeanDefinition
//確保此時確實解析了bean類,若是動態解析的類沒法存儲在共享的合併bean定義中,則複製bean定義。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
//2.準備方法覆蓋,好比<lookup-method/>
try {
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.
//3.經過BeanPostProcessor返回代理Bean,這個BeanPostProcessor必須是非用戶自定義的
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);
}
//4.常規建立bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
複製代碼
這個方法用來建立實例,首先會解析BeanDefinition
,設置BeanDefinition
的一些相關屬性;而後是經過BeanPostProcessor
來返回一個代理Bean
,實現短路操做;最後是真正的去建立Bean
。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
:
/** * 真實的建立Bean,並執行回調 */
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//1.獲取Java對象,包括工廠方法(實例工廠、靜態工廠)、有參構造、默認構造
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//2.獲取bean
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
// 3.執行後置處理器修改MergeBeanDefinition
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;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//4.是否須要提早曝光,用來解決循環依賴時使用
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");
}
//解決循環依賴,匿名內部類用於回調
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//5.填充Bean,如屬性等
//若是依賴其餘的bean,則會初始化被依賴的bean
//循環依賴也是在這裏處理的
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//6.執行回調方法,如Aware、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) {
//在檢查到循環依賴的狀況下,不爲NULL
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);
}
}
//說明被依賴的bean沒有徹底建立,也就是說循環依賴沒有解決
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.");
}
}
}
}
// Register bean as disposable.
try {
//註冊銷燬方法,如DisposableBean、destroy-method等
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
複製代碼
這個方法用於真正的建立Bean
實例,首先調用createBeanInstance
方法經過反射建立Java對象;而後調用addSingletonFactory
方法放入三級緩存(singletonFactories
),用於解決循環引用的問題;而後調用populateBean
方法進行依賴注入以及調用initializeBean
方法進行初始化方法回調和BeanPostProcessor
回調;最後調用registryDisposableBeanIfNecessary
方法註冊銷燬回調方法。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
:
/** * 根據指定的bean建立bean instance * 實例化策略:factory method、constructor autowiring、simple instantiation */
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//1.工廠方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Candidate constructors for autowiring?
//2.有參構造,按類型匹配
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
//3.默認構造方法
return instantiateBean(beanName, mbd);
}
複製代碼
實例Bean
主要有三種方式:工廠方法(靜態工廠、工廠方法)、有參構造、無參構造。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean
:
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
//1.實例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//2.封裝
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
複製代碼
該方法將建立的Bean
實例封裝爲BeanWrapper
並返回。
org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate
:
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
//1.若是沒有方法覆蓋(如<lookup-method/>或@Lookup),不須要使用CGLIB生成代理類
if (bd.getMethodOverrides().isEmpty()) {
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
//2.使用CGLIB生成代理類
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
複製代碼
判斷該BeanDefinition
是否有方法覆蓋,若是存在,則使用CGLIB
動態代理生成代理對象,不然,直接建立當前實例。
org.springframework.beans.BeanUtils#instantiateClass
:
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
}
複製代碼
經過反射建立Java對象並返回。至此,Spring實例化Bean
的過程也就完成了,後續就調用上述的依賴注入、初始化回調、BeanPostPorcessor
、銷燬回調等方法,最後放入到一級緩存中。
總結一下:
1.在
BeanDefinition
準備好以後,須要調用finishBeanFactoryInitialization
方法對beanDefinitionNames
進行遍歷,單例的非懶加載的Bean
進行預實例化。2.對
beanDefinitionName
進行轉換,爲了解決FactoryBean
的轉義符&
,而後從IOC的三個緩存(singletonObjects
、earlySingletonObjects
、singletonFactories
)中判斷要預實例化的bean
是否已經存在,若是存在,則直接返回(而後調用getObjectForBeanInstance
方法,判斷若是是bean
,直接返回,若是是FactoryBean
,則返回FactoryBean#getObject
產生的對象),若是不存在,則判斷beanDefinition
的做用域,根據做用域走不一樣的路徑。3.對於
Singleton
做用域的beanDefinition
,經過調用DefaultSingletonBeanRegistry#getSingleton
方法獲取實例,在這個方法中首先會把這個bean
加入到正在建立的集合中, 而後調用匿名內部類的ObjectFactory#createBean
方法建立實例,以後把該bean
從建立的集合中移除,並加入IOC的一級緩存(singletonObjects
)中,那也就完成了預實例化。4.匿名內部類
ObjectFactory
其中一個重要的實現類AbstractAutowireCapableBeanFactory
,該類是實例化bean
的核心類,在createBean
方法中是爲了後面的doCreateBean
作準備,好比方法覆蓋、短路返回代理bean
等;doCreateBean
方法調用createBeanInstance
方法經過反射進行了實例化,createBeanInstance
方法包含了工廠方法(實例工廠、靜態工廠)、有參構造、無參構造三種實例化方式;拿到實例化對象以後,爲了解決循環依賴,須要把ObjectFactory
放到三級緩存中(singletonFactories
),ObjectFactory
包括了當前建立的beanName
、BeanDefinition
、bean
;調用populateBean
方法進行依賴注入(深拷貝),依賴注入的時候會解決循環依賴,會把循環依賴的實例放入二級緩存(earlySingletonObjects
);調用initalizeBean
回調BeanPostProcessor
的方法以及一些初始化回調方法、Aware
方法等;後續注入銷燬方法。最後調用getObjectForBeanInstance
方法,判斷若是是bean
,直接返回,若是是FactoryBean
,則返回FactoryBean#getObject
產生的對象。5.至此,預實例化也就完成了,當
getBean
的時候就會調用DefaultSingletonBeanRegistry#getSingleton
從一級緩存(singletonObjects
)中獲取(以後調用getObjectForBeanInstance
方法,判斷若是是bean
,直接返回,若是是FactoryBean
,則返回FactoryBean#getObject
產生的對象)。
在瞭解完singleton
以後,對於prototye
就相對簡單的多了,prototype
是隻有當咱們調用的時候纔會建立,而且不會被緩存。
test
:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TestB testB = applicationContext.getBean(TestB.class);
複製代碼
applicationContext.xml
:
<bean id="testB" class="com.ly.entity.cycle.TestB" scope="prototype">
<property name="name" value="5555"/>
</bean>
複製代碼
上述代碼申明瞭一個prototype
的bean
,那麼它只有當咱們使用到這個bean
的時候纔會被調用,因此getBean
就是該bean
實例化的入口。
org.springframework.context.support.AbstractApplicationContext#getBean
:
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
//1.斷言
assertBeanFactoryActive();
//2.實例化BeanDefinition的時候建立的BeanFactory,通常是DefaultListableBeanFactory
return getBeanFactory().getBean(requiredType);
}
複製代碼
org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean
:
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
@Override
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
//1.這是對bean和beanName的封裝
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
//2.當前容器沒找到這個bean,則從父容器中獲取
BeanFactory parent = getParentBeanFactory();
if (parent != null) {
return parent.getBean(requiredType, args);
}
//3.都沒有,則拋出異常
throw new NoSuchBeanDefinitionException(requiredType);
}
複製代碼
org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveNamedBean
:
private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
//1.beanNames
String[] candidateNames = getBeanNamesForType(requiredType);
//2.只有一個名稱
if (candidateNames.length == 1) {
String beanName = candidateNames[0];
return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args));
}
return null;
}
複製代碼
這部分源碼省略了多個名稱的狀況,對於只有單個名稱的bean
,經過NamedBeanHolder
封裝了beanName
和getBean
獲取的bean
。這裏的getBean
仍是回到了和singleton
同樣的方法中。
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
:
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
//轉換beanName,爲了解決FactoryBean的&符號
final String beanName = transformedBeanName(name);
Object bean;
//2.若是這個bean是原型bean,而且已經在建立中了,則拋出異常,循環引用問題
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//8.原型
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
return (T) bean;
}
複製代碼
這部分源碼省略了不少關於singleton
的,只須要關注這裏便可。首先將要建立的這個bean
放入一個ThreadLocal
中,若是循環引用的時候,會判斷bean
已經在建立中了,會拋出異常,這也是prototype
不支持循環引用的緣由;而後調用createBean
方法建立bean
,這和singleton
是如出一轍的;最後從ThreadLocal
中移除,而後根據getObjectForBeanInstance
方法判斷這個bean
是普通的bean
仍是FactoryBean
,若是是普通bean
,則直接返回,若是是FactoryBean
,則返回FactoryBean#getObejct
方法產生的對象。
至此,prototype
的bean
的建立過程也就完成了。