源碼分析基於spring 4.3.xjava
前面文章已經分析了spring如何加載xml配置中的bean元數據,如今來分析一下spring構造bean的過程。
關於閱讀源碼的思路,可參考 -- 如何閱讀java源碼spring
BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("application.xml")); Blog bean = (Blog)xmlBeanFactory.getBean("blog");
XmlBeanFactory的父類AbstractBeanFactory是spring中一個很重要的類,他爲BeanFactory提供基礎服務。構造bean就是由該類實現的。
AbstractBeanFactory#doGetBean緩存
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; Object sharedInstance = getSingleton(beanName); // #1 if (sharedInstance != null && args == null) { ... bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); // #2 } else { if (isPrototypeCurrentlyInCreation(beanName)) { // #3 throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // #4 ... } if (!typeCheckOnly) { markBeanAsCreated(beanName); // #5 } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // #6 checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); 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); try { getBean(dep); // #7 } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { // #8 try { return createBean(beanName, mbd, args); // #9 } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } ... } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { // #10 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; }
#1
單例的bean,先從緩衝中查詢
getSingleton方法會查詢
singletonObject,earlySingletonObjects,singletonFactories等緩存,它們都是簡單的map,緩存了單例的bean,正在建立的bean和ObjectFactory對象。微信
#2
若是構造的bean是FactoryBean,進行對應的處理
getObjectForBeanInstance方法會根據參數beanInstance進行處理,若是beanInstance是FactoryBean,會調用其getObject()
方法建立bean,若是不是,返回直接返回該beanInstance參數。
FactoryBean是spring提供的一個擴展接口,用戶實現該接口能夠自定義bean的建立。app
#3
若是如今正在建立這個bean,則直接報錯,這時極可能陷入循環引用了#4
當前BeanFactory不存在對應的BeanDefinition,嘗試經過父BeanFactory構造bean#5
標記這個bean正在構造中#6
獲取BeanDefinition
前面解析spring加載bean數據的文章中說過,spring會將bean元數據轉化爲BeanDefinition,存入DefaultListableBeanFactory#beanDefinitionMap屬性中。
getMergedLocalBeanDefinition方法會獲取對應BeanDefinition,若是BeanDefinition存在ParentName,會獲取父BeanDefinition,再合併元數據。ide
#7
先構造依賴的bean#8
使用ObjectFactory構造並註冊一個bean,getSingleton方法也要完成構造bean的準備和藹後工做。#9
匿名的ObjectFactory,調用AbstractAutowireCapableBeanFactory#createBean進行實際的構造bean工做#10
bean類型轉換函數
spring中bean有singleton,prototype等範圍,這裏只關注singleton類型的bean的構造過程。源碼分析
#8
步驟,DefaultSingletonBeanRegistry#getSingleton(注意getSingleton有重載方法)post
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { ... beforeSingletonCreation(beanName); // #1 boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { singletonObject = singletonFactory.getObject(); // #2 newSingleton = true; } ... finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); // #3 } } return singletonObject; } }
#1
僅作錯誤檢查,也是提供給子類的擴展方法#2
真正構造bean的方法,調用AbstractBeanFactory#doGetBean方法#9
步驟的匿名類處理,實際調用AbstractAutowireCapableBeanFactory#createBean#3
單例的bean,加入緩衝中ui
真正的構造bean方法
AbstractAutowireCapableBeanFactory#createBean
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; Class<?> resolvedClass = resolveBeanClass(mbd, beanName); // #1 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); // #2 } ... try { Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // #3 if (bean != null) { return bean; } } ... try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); // #4 if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } ... }
#1
確保jdk已加載bean的class#2
對bean的lookup-method和replace-method作檢查工做#3
spring的擴展機制,調用BeanPostProcessor#postProcessBeforeInstantiation方法,
注意,若是resolveBeforeInstantiation返回非null對象,這裏將直接返回該對象做爲bean,spring再也不構造該bean。#4
繼續構造bean
AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); // #1 } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); // #2 } final Object bean = instanceWrapper.getWrappedInstance(); 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 { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); // #3 } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } ... // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); // #4 exposedObject = initializeBean(beanName, exposedObject, mbd); // #5 } 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); } } ... // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); // #6 } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
#1
查詢BeanWrapper緩衝#2
構造一個空的(屬性未注入)bean,生成BeanWrapper#3
spring擴展機制,調用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition#4
populateBean負責注入屬性到bean中,後面有對應文章解析該步驟#5
spring擴展機制,調用Aware方法和init方法,並調用BeanPostProcessor#postProcessAfterInitialization方法。#6
若是bean存在Destroy方法,或存在對應的DestructionAwareBeanPostProcessor,註冊該bean爲disposable。(該bean銷燬時要調用對應的銷燬機制)
這裏涉及到循環引用的處理,比較繁瑣,因此省略了不少代碼,只保留bean建立相關的代碼。
BeanWrapper是對bean的包裝類,提供了對bean的class,property進行操做的方法。
#2
步驟,AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { Class<?> beanClass = resolveBeanClass(mbd, beanName); // #1 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()); } if (mbd.getFactoryMethodName() != null) { // #2 return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { // #3 resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); // #4 } else { return instantiateBean(beanName, mbd); // #5 } } Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // #6 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); }
#1
獲取bean的class #2
若是存在factoryMethod,經過factoryMethod構造bean#3
判斷該class已經構造過bean了#4
使用以前選擇好的構造函數構造bean#5
使用無參構造函數構造bean#6
spring根據構造函數的參數,自行選擇構造函數,邏輯較複雜。
下面看看使用無參構造方法構造bean,AbstractAutowireCapableBeanFactory#instantiateBean -> SimpleInstantiationStrategy#instantiate
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) { if (bd.getMethodOverrides().isEmpty()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { ... } else { constructorToUse = clazz.getDeclaredConstructor((Class[]) null); // #1 } bd.resolvedConstructorOrFactoryMethod = constructorToUse; // #2 } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } return BeanUtils.instantiateClass(constructorToUse); // #3 } else { return instantiateWithMethodInjection(bd, beanName, owner); // #4 } }
#1
獲取無參構造函數#2
添加無參構造函數加入到BeanDefinition緩存中#2
BeanUtils#instantiateClass經過構造函數構造bean#3
bean中存在lookup-method或replace-method,必須使用CGLIB構造bean
到這裏,bean已經構造完成,下一步就是注入屬性了。
若是您以爲本文不錯,歡迎關注個人微信公衆號,您的關注是我堅持的動力!