廣西城鄉(xiāng)建設廳網站外貿seo網站推廣
spring-framework 版本:v5.3.19
文章目錄
- bean的加載
- bean的創(chuàng)建
- 總結
- getBean流程
- createBean流程
- doCreateBean流程
bean的加載
beanFactory的genBean最常用的一個實現(xiàn)就是AbstractBeanFactory.getBean()。
以ApplicationContext為例,流程是: ApplicationContext.getBean()----》BeanFactory.getBean()----》AbstractBeanFactory.getBean()
而真正做事情的是deGetBean方法
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {//獲取beanNameString beanName = transformedBeanName(name);Object beanInstance;//無論是什么作用域都先嘗試從單例池獲取Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}//有時候并不是放回實例本身,而是返回其映射的實例。如:BeanFactory情況下返回指定方法返回的實例beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {//當原型模式下有循環(huán)依賴時,拋異常(原型模式下若存在循環(huán)依賴會導致內存泄漏)if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}//嘗試從父beanFactory加載beanBeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}//如果不是僅僅做類型檢查則是創(chuàng)建bean,這里進行記錄if (!typeCheckOnly) {markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}//得到合并后的beanDefinitionRootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);//檢查beanDefinition,抽象的beanDefinition會報錯checkMergedBeanDefinition(mbd, beanName, args);//先加載dependsOn標注的beanString[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {//dePendsOn引起的循環(huán)依賴,拋異常if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}//注冊dependentBeanMap(dependsOn 于哪些bean)和注冊dependenciesForBeanMap(被哪些bean dependOn)registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}//-----------------------------------開始創(chuàng)建bean-----------------------------------------------//單例模式if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}});beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}//原型模式else if (mbd.isPrototype()) {Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}//其他模式else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");}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, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;}finally {beanCreation.end();}}//必要時進行類型轉換return adaptBeanInstance(name, beanInstance, requiredType);}
bean的創(chuàng)建
從bean的加載中得知,當一個從緩存中獲取不到的時候就會調用createBean方法去創(chuàng)建一個bean。而在AbstractBeanFactory中這是一個抽象方法,具體的創(chuàng)建邏輯由具體的beanFactory類自行實現(xiàn)。至少目前為止,spring內置的實現(xiàn)只有AbstractAutowireCapableBeanFactory.createBean()。無論是AnnotationConfigApplicationContext還是ClassPathXmlApplicationContext創(chuàng)建bean的邏輯最終都會來到這個方法。
雖然AnnotationConfigApplicationContext和ClassPathXmlApplicationContext并不直接繼承AbstractAutowireCapableBeanFactory。但是都維護了一個DefaultListableBeanFactory成員變量,而這個成員變量繼承自AbstractAutowireCapableBeanFactory。
createBean
doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {//如果是單例,factoryBeanCache.removeBeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}//實例化beanif (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}//MergedBeanDefinitionPostProcessor的應用(如:AutowiredAnnotationBeanPostProcessor)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;}}//提前暴露bean,循環(huán)依賴處理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));}Object exposedObject = bean;try {//屬性填充//填充屬性之前會調用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation//填充屬性之后會調用 InstantiationAwareBeanPostProcessor.postProcessProperties --如果返回null--> postProcessPropertyValuespopulateBean(beanName, mbd, instanceWrapper);//初始化bean(是指據(jù)配置自定義的初始化bean如:@PostConstruct,而不是指構造方法的初始化)//初始化之前會調用 PostProcessors.postProcessBeforeInitialization//初始化之后會調用 PostProcessors.postProcessAfterInstantiationexposedObject = 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);}}//循環(huán)依賴檢查,判斷是否需要拋出異常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.");}}}}//注冊DisposableBean,如果配置了destroy-methoy,這里需要注冊以便于在銷毀的時候調用try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}
initializeBean
總結
getBean流程
1:transformedBeanName(name) 轉換為對應的beanName
2:getSingleton(beanName) 嘗試從緩存中加載單例
3:isPrototypeCurrentlyIncreation(beanName) 原型模式的依賴檢查
4:檢測父BeanFactory
5:getMergedLocalBeanDefinition(beanName) GernericBeanDefinition轉換為RootBeanDefinition
6:依賴檢測
7:根據(jù)不同的模式創(chuàng)建bean
8:getObjectForBeanInstance(prototypeInstance, name, beanName, mbd) 根據(jù)得到的Bean獲取真正對象
9:如果需要則做類型轉換
createBean流程
1:鎖定class
2:指定方法的覆蓋
3:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
4:doCreateBean
doCreateBean流程
1:若為單例,移除factoryBeanCache內的緩存
2:實例化Bean
3:MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(如:AutowiredAnnotationBeanPostProcessor)
4:提前暴露bean,循環(huán)依賴處理
(populateBean)
5:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
6:屬性填充
7:InstantiationAwareBeanPostProcessor.postProcessProperties --如果返回null–> postProcessPropertyValues
(initializeBean)
8:aware方法的執(zhí)行(beanNameAware,beanClassLoaderAware,beanFactoryAware)
9:PostProcessors.postProcessBeforeInitialization
10:自定義初始化bean(如:InitializingBean.afterPropertiesSet,@PostConstruct,init-method)
11:PostProcessors.postProcessAfterInstantiation
12:循環(huán)依賴檢查,判斷是否需要拋出異常
13:注冊DisposableBean