前言
接的私活有點(diǎn)趕進(jìn)度,加上周四搬工位,昨天看了演唱會(huì),加上改bug一直沒有抽出時(shí)間來寫,今天估計(jì)補(bǔ)不上周四的了,周末也有事情,周四的下周一定不上。廢話不說了,我們繼續(xù)之前bean的加載下篇,bean的加載是spirng-ioc的核心,我自己理解的也不是特別好,有感興趣的小伙伴歡迎一起聊聊。
QQ:616516146,Gmail:liangliang1259@gmail.com。
1、getBean()
這個(gè)方法有點(diǎn)長我們進(jìn)行分段解析。
1.1、從緩存獲取
//提取對(duì)應(yīng)的beanName
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**
* 檢查緩存中或者實(shí)例工廠中是否有對(duì)應(yīng)實(shí)例
* 為何會(huì)首先使用這段代碼
* 因?yàn)樵趧?chuàng)建單例bean的時(shí)候會(huì)存在依賴注入的情況,而在創(chuàng)建依賴的時(shí)候?yàn)榱吮苊庋h(huán)依賴
* Spring創(chuàng)建Bean的原則是不等bean創(chuàng)建完成就會(huì)將創(chuàng)建Bean的ObjectFactory提早曝光
* 也就是講ObjectFactory加入到緩存中,一旦下一個(gè)bean創(chuàng)建的時(shí)候需要依賴上個(gè)bean則直接使用ObjectFactory
*/
//嘗試從混成或者singletonFactories中的ObjectFactory中獲取
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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
這個(gè)方法首先從緩存中去獲取,這個(gè)時(shí)候緩存中當(dāng)然沒有數(shù)據(jù),因?yàn)榇藭r(shí)是初始化,我們還沒有將bean方到singletonObjects這個(gè)map中去,如下圖代碼。
1.1.1、getSingleton()
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//檢查緩存中是否存在實(shí)例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//若不存在則鎖定全局變量進(jìn)行處理
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//調(diào)用預(yù)先設(shè)定的getObject方法
singletonObject = singletonFactory.getObject();
//記錄在緩存中,earlySingletonObjects和singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
1.2、獲取beanFacotry
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//如果beaDefinitionMap中也就是在所有已經(jīng)加載的類中不包括beanName則嘗試從parentBeanFactory中檢測(cè)
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) {
//遞歸到BeanFactory中去尋找
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
這段代碼首先獲取該bean的父類,若有父類則用父類去實(shí)例化該bean,這里的parentBeanFactory為null,暫時(shí)不做考慮。接下來看第三部分。
1.3
//如果不是做類型檢查則是創(chuàng)建bean,這里要進(jìn)行記錄
//第一部分
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//第二部分
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
//若存在依賴則需要遞歸實(shí)例化依賴的bean
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);
getBean(dep);
}
}
//第三部分
// Create bean instance.
//實(shí)例化依賴的bean之后可以實(shí)例化mbd本身了
//單例模式的創(chuàng)建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
/**
*核心創(chuàng)建bean
*/
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初始化處理
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
- 1、第一部分,標(biāo)記目前的bean屬于正在創(chuàng)建狀態(tài)
- 2、第二部分,根據(jù)beanName獲取該bean在beanFactory中的beanDefinitionMap中beanDefinition,然后獲取該bean所依賴的bean(此處是spring解決循環(huán)依賴的關(guān)鍵),如果依賴的bean還未創(chuàng)建,則先創(chuàng)建依賴的bean,依次遞歸調(diào)用(DI依賴注入的概念),如果找不到依賴,則忽略。
- 3、若是單例,創(chuàng)建bean,調(diào)用CreateBean()方法,此處只考慮單例模式
接下來跟蹤createBean()方法。此處調(diào)用的是AbstractAutowireCapableBeanFactory中的方法
1.4、createBean()
//第一部分
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.
/**
* 鎖定class,根據(jù)設(shè)置的class屬性或者根據(jù)classname來解析class
*/
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//第二部分
//驗(yàn)證及準(zhǔn)備覆蓋的方法
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.
//給BeanPostProcessors一個(gè)機(jī)會(huì)來返回代理來代替真正的實(shí)例,前置處理器
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
/**
* 前置處理后返回結(jié)果不為空,直接返回結(jié)果,AOP功能就是基于這里判斷的
*/
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.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
- 1、第一部分:確保該bean的class是真實(shí)存在的,也就是該bean是可以classload可以找到加載的,若不存在則放入beanDefination中
- 2、第二部分:準(zhǔn)備方法的重寫
- 3、第三部分:(重要)最后的return就是返回的bean,但看注釋:Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.這邊就很清晰了,我們以前在beanPostProcessor的章節(jié)講過,beanPostProcessor是可以臨時(shí)修改bean的,它的優(yōu)先級(jí)高于正常實(shí)例化bean的(也就是第四部分實(shí)例化的方法)如果beanPostProcessor能返回,則直接返回了,這邊代碼下次分析,我們還是先分析主要流程:
- 4、doCreateBean(beanName, mbd, args)這個(gè)方法,接下來看這個(gè)
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根據(jù)指定的bean使用對(duì)應(yīng)的側(cè)臉創(chuàng)建新的實(shí)例,如工廠方法,構(gòu)造函數(shù)自動(dòng)注入,簡單初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
if (beanType != null) {
// 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;
}
}
}
這里首先初始化一個(gè)instanceWrapper,然后再看createBeanInstance()
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);
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);
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same 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) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
這塊代碼主要是再次對(duì)bean做安全檢查并確定該bean有默認(rèn)的構(gòu)造函數(shù),createBeanInstance()這個(gè)方法最后一行
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
然后我們?cè)倩氐絛oCreateBean()這個(gè)方法,在AbstractAutowireCapableBeanFactory
// Initialize the bean instance.
Object exposedObject = bean;
try {
//對(duì)bean進(jìn)行填充,將各個(gè)屬性值注入,其中,可能存在依賴與其他bean的屬性,則會(huì)遞歸初始依賴bean
populateBean(beanName, mbd, instanceWrapper);// sunliang marked
if (exposedObject != null) {
//調(diào)用初始化方法,比如init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
初始化bean,的確,現(xiàn)在bean已經(jīng)實(shí)例化了,開始初始化該bean,進(jìn)入initializeBean(...)這個(gè)方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
接下來進(jìn)入到invokeAwareMethods()方法
private void invokeAwareMethods(final String beanName, final 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);
}
}
}
再回到initializeBean()方法中
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("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();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//第二部分
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
首先先判斷該bean是否實(shí)現(xiàn)了InitializingBean,如果實(shí)現(xiàn)了先執(zhí)行afterPropertiesSet這個(gè)方法,然后如果該bean又執(zhí)行了init-method,到此我們的bean創(chuàng)建和加載算是基本完成,下一節(jié)分析一些具體詳細(xì)點(diǎn)的實(shí)現(xiàn)。