Spring创建Bean的过程Debug 目录

由于Spring-Content中的ApplicationContent是整个IOC的入口。我们导入Spring-context包即可

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->org.springframeworkspring-context5.2.3.RELEASE

我们导入spring-content后,默认会导入该组件的依赖jar,spring-content底层的依赖可以看到,实际上我们是导入了Core Container模块:

org.springframeworkspring-aop5.2.3.RELEASEcompileorg.springframeworkspring-beans5.2.3.RELEASEcompileorg.springframeworkspring-core5.2.3.RELEASEcompileorg.springframeworkspring-expression5.2.3.RELEASEcompile

新建Spring配置文件spring.xml:

<?xml version="1.0" encoding="UTF-8"?><!--注册一个对象,spring回自动创建这个对象--><!--

    一个bean标签就表示一个对象

    id:这个对象的唯一标识

    class:注册对象的完全限定名

    --><!--使用property标签给对象的属性赋值

        name:表示属性的名称

        value:表示属性的值

        -->

编写测试类:

importcom.xiaodai.service.Hello;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassTest{publicstaticvoid main(String[] args) {ApplicationContextapplicationContext = newClassPathXmlApplicationContext("spring.xml");Hellohello = applicationContext.getBean("hello",Hello.class);System.out.println(hello.getName());    }}

1.2 Debug容器创建过程

从测试类的new ClassPathXmlApplicationContext("spring.xml")开始debug,进入ClassPathXmlApplicationContext,可以看到:

publicClassPathXmlApplicationContext(String[] configLocations,booleanrefresh,@NullableApplicationContext parent)throwsBeansException{super(parent);// 设置配置文件路径setConfigLocations(configLocations);if(refresh) {// 核心步骤refresh();}}

加载配置文件后,进入refresh()方法,该方法是容器初始化的核心步骤。该方法包含十三个方法:

@Overridepublicvoidrefresh()throwsBeansException, IllegalStateException{synchronized(this.startupShutdownMonitor) {// Prepare this context for refreshing./**

* 准备刷新,做一些最基本的准备化工作

**/prepareRefresh();// Tell the subclass to refresh the internal bean factory./**

* 获得一个刷新的bean容器,实质就是获取工厂。

* 加载xml等配置文件,用该文件产生的BeanDefinition来创建一个工厂

**/ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context./**

* 准备bean工厂

**/prepareBeanFactory(beanFactory);try{// Allows post-processing of the bean factory in context subclasses.// 后置增强,方便扩展postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.// 实例化并且执行BeanFactoryPostProcessorsinvokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.// 实例化并且注册所有的BeanPostProcessorregisterBeanPostProcessors(beanFactory);// Initialize message source for this context.// 国际化设置,一般用不到initMessageSource();// Initialize event multicaster for this context.// 初始化应用程序的多波器和广播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 空方法,预留给子类做扩展onRefresh();// Check for listener beans and register them.// 注册监听器registerListeners();// Instantiate all remaining (non-lazy-init) singletons.// 工作中常用,面试常问。实例化所有非懒加载的实例对象finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.// 完成刷新finishRefresh();}catch(BeansException ex) {if(logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - "+"cancelling refresh attempt: "+ ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throwex;}finally{// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}

1.3 AbstractApplicationContext的refresh()包含的13个方法分析

结合概览图一个一个方法分析:

方法1:prepareRefresh() => 准备工作

准备刷新,做一些最基本的准备化工作

protectedvoidprepareRefresh(){// Switch to active.// 设置开始时间this.startupDate = System.currentTimeMillis();// 关闭状态设置为falsethis.closed.set(false);// 活跃状态设置为truethis.active.set(true);// 打印日志if(logger.isDebugEnabled()) {if(logger.isTraceEnabled()) {logger.trace("Refreshing "+this);}else{logger.debug("Refreshing "+ getDisplayName());}}// Initialize any placeholder property sources in the context environment.// 初始化属性资源initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredProperties// 获取环境信息,验证属性信息getEnvironment().validateRequiredProperties();// Store pre-refresh// 存储预刷新的一些应用信息的监听器ApplicationListeners...if(this.earlyApplicationListeners ==null) {this.earlyApplicationListeners =newLinkedHashSet<>(this.applicationListeners);}else{// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...// 创建一些监听器事件的集合this.earlyApplicationEvents =newLinkedHashSet<>();}

总结:1.设置启动事件 2.设置关闭活跃的状态 3.获取环境对象并设置属性值 4.设置监听器以及需要发布事件的集合

重要的点:

获取环境信息,验证属性信息,getEnvironment().validateRequiredProperties();

存储预刷新的一些应用信息的监听器,在Spring中是空实现,但是SpringBoot中,是有具体的值的

方法2:obtainFreshBeanFactory() => 获得一个刷新的bean容器

获得一个刷新的bean容器,实质就是获取工厂。创建容器对象DefaultListableBeanFactory;加载xml配置文件的属性到当前的工厂中,最重要的就是BeanDefinition

AbstractRefreshableApplicationContext:

// 只要进到这个方法,那么我们创建的一定是一个新的工厂@OverrideprotectedfinalvoidrefreshBeanFactory()throwsBeansException{if(hasBeanFactory()) {// 如果存在先销毁,后关闭destroyBeans();closeBeanFactory();}try{// 创建bean工厂,这里使用的就是DefaultListableBeanFactory。此时创建的工厂里面的属性值都是默认值DefaultListableBeanFactory beanFactory = createBeanFactory();// 序列化idbeanFactory.setSerializationId(getId());// 设置一些属性值customizeBeanFactory(beanFactory);// 加载bean的定义属性值。该方法有很多重载,非常复杂,核心是do操作// 完成配置文件或者配置类文件的加载loadBeanDefinitions(beanFactory);synchronized(this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch(IOException ex) {thrownewApplicationContextException("I/O error parsing bean definition source for "+ getDisplayName(), ex);}}

方法3:prepareBeanFactory(beanFactory) => 准备(初始化)Bean工厂

为方法2拿到的工厂,设置某些具体的值

protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory){// Tell the internal bean factory to use the context's class loader etc.// 为bean工厂设置类加载器beanFactory.setBeanClassLoader(getClassLoader());// 设置SPEL解析器beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(newResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 添加一个BeanPostProcessorbeanFactory.addBeanPostProcessor(newApplicationContextAwareProcessor(this));// 忽略对应接口的实现beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.// 注册一些依赖beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class,this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class,this);beanFactory.registerResolvableDependency(ApplicationContext.class,this);// Register early post-processor for detecting inner beans as// ApplicationListeners添加一个BeanPostProcessor增强器ApplicationListeners.beanFactory.addBeanPostProcessor(newApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if(beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.if(!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if(!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if(!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}

方法4:postProcessBeanFactory(beanFactory) => 后置增强Bean(扩展实现)

空方法,方便扩展

方法5:invokeBeanFactoryPostProcessors(beanFactory) => 执行BFPP

实例化并且执行BeanFactoryPostProcessors

/**

* Instantiate and invoke all registered BeanFactoryPostProcessor beans,

* respecting explicit order if given.

* <p>Must be called before singleton instantiation.

* 单例对象之前一定调用,因为单例bean创建后就只有一份

*/protectedvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory){PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if(beanFactory.getTempClassLoader() ==null&& beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}

方法6:registerBeanPostProcessors(beanFactory) => 注册BPP

实例化并且注册所有的BeanPostProcessor。实例化Bean之前的准备工作

/**

* Instantiate and register all BeanPostProcessor beans,

* respecting explicit order if given.

* <p>Must be called before any instantiation of application beans.

*/protectedvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory){PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory,this);}

方法7:initMessageSource() => 国际化设置

方法8:initApplicationEventMulticaster() => 初始化应用程序的多波器和广播器

也属于准备工作

方法9:onRefresh() => 预留给子类做扩展

空方法

方法10:registerListeners() => 注册监听器

也属于准备工作

/**

* Add beans that implement ApplicationListener as listeners.

* Doesn't affect other listeners, which can be added without being beans.

*/protectedvoidregisterListeners(){// Register statically specified listeners first.for(ApplicationListener listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let post-processors apply to them!String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class,true,false);for(StringlistenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}// Publish early application events now that we finally have a multicaster...Set earlyEventsToProcess =this.earlyApplicationEvents;this.earlyApplicationEvents =null;if(earlyEventsToProcess !=null) {for(ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}

方法11:finishBeanFactoryInitialization(beanFactory) => 实例化所有单例对象

面试常问,工作常用。过程比较复杂

/**

* Finish the initialization of this context's bean factory,

* initializing all remaining singleton beans.

*/protectedvoidfinishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory){// Initialize conversion service for this context./**

* 把类型转化操作,设置到当前的beanFactory里面去

**/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));}// Register a default embedded value resolver if no bean post-processor// (such as a PropertyPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values./**

* 判断当前的beanFactory有没有内置的值处理器

**/if(!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early./**

* 织入Aware

**/String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class,false,false);for(String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.// 设置类加载器beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes./**

* 冻结:某些bean不需要进行修改操作了,放入

**/beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons./**

* 实例化所有非懒加载的实例对象(重要)

**/beanFactory.preInstantiateSingletons();}

实例化所有非懒加载的实例对象方法:

@OverridepublicvoidpreInstantiateSingletons()throwsBeansException{if(logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in "+this);}// 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./**

* 拿到所有注册bean的名称

**/List beanNames =newArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...// 循环去创建我们需要的单例对象for(String beanName : beanNames) {// 拿到bean的定义信息,就是我们在xml配置文件里面指定的一些属性RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);// 是否是抽象的,是否是单例的,是否是懒加载的if(!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// 判断当前类是否实现了factoryBean接口。一般没实现,直接进入下面的getBeanif(isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if(beaninstanceofFactoryBean) {finalFactoryBean factory = (FactoryBean) bean;booleanisEagerInit;if(System.getSecurityManager() !=null&& factoryinstanceofSmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction)((SmartFactoryBean) factory)::isEagerInit,getAccessControlContext());}else{isEagerInit = (factoryinstanceofSmartFactoryBean &&((SmartFactoryBean) factory).isEagerInit());}if(isEagerInit) {getBean(beanName);}}}else{// 通过beanName。拿到beangetBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for(String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if(singletonInstanceinstanceofSmartInitializingSingleton) {finalSmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if(System.getSecurityManager() !=null) {AccessController.doPrivileged((PrivilegedAction) () -> {smartSingleton.afterSingletonsInstantiated();returnnull;}, getAccessControlContext());}else{smartSingleton.afterSingletonsInstantiated();}}}}

重要方法:

getMergedLocalBeanDefinition

/** * Return a merged RootBeanDefinition, traversing the parent bean definition * if the specified bean corresponds to a child bean definition. *@parambeanName the name of the bean to retrieve the merged definition for *@returna (potentially merged) RootBeanDefinition for the given bean *@throwsNoSuchBeanDefinitionException if there is no bean with the given name *@throwsBeanDefinitionStoreException in case of an invalid bean definition */// 返回一个合并好的RootBeanDefinition。整合子类和父类protectedRootBeanDefinitiongetMergedLocalBeanDefinition(String beanName)throwsBeansException{// Quick check on the concurrent map first, with minimal locking.RootBeanDefinition mbd =this.mergedBeanDefinitions.get(beanName);if(mbd !=null&& !mbd.stale) {returnmbd;}returngetMergedBeanDefinition(beanName, getBeanDefinition(beanName));}

getBean() => doGetBean()

/** * Return an instance, which may be shared or independent, of the specified bean. *@paramname the name of the bean to retrieve *@paramrequiredType the required type of the bean to retrieve *@paramargs arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) *@paramtypeCheckOnly whether the instance is obtained for a type check, * not for actual use *@returnan instance of the bean *@throwsBeansException if the bean could not be created */@SuppressWarnings("unchecked")protectedTdoGetBean(finalString name,@NullablefinalClass requiredType,@NullablefinalObject[] args,booleantypeCheckOnly)throwsBeansException{// 获取beanNamefinalString beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons.// 单例检查,如果一级,二级,三级缓存中存在该Bean,直接获取到了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 +"'");}}bean = getObjectForBeanInstance(sharedInstance, name, beanName,null);}else{// Fail if we're already creating this bean instance:// We're assumably within a circular reference.// 如果是单例对象的话,尝试解决循环依赖问题if(isPrototypeCurrentlyInCreation(beanName)) {thrownewBeanCurrentlyInCreationException(beanName);}// Check if bean definition exists in this factory.// 获取父类容器BeanFactory parentBeanFactory = getParentBeanFactory();if(parentBeanFactory !=null&& !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if(parentBeanFactoryinstanceofAbstractBeanFactory) {return((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}elseif(args !=null) {// Delegation to parent with explicit args.return(T) parentBeanFactory.getBean(nameToLookup, args);}elseif(requiredType !=null) {// No args -> delegate to standard getBean method.returnparentBeanFactory.getBean(nameToLookup, requiredType);}else{return(T) parentBeanFactory.getBean(nameToLookup);}}// 标志位。如果不是类型检查,表示要创建bean,此处在集合中做一个记录if(!typeCheckOnly) {markBeanAsCreated(beanName);}try{// 获取beanDefinitionfinalRootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检测beanDefinitioncheckMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.// 检查当前的bean是否有其他依赖的beanString[] dependsOn = mbd.getDependsOn();if(dependsOn !=null) {// 如果有依赖的bean,我们要先递归解决其他依赖的beanfor(String dep : dependsOn) {if(isDependent(beanName, dep)) {thrownewBeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '"+ beanName +"' and '"+ dep +"'");}registerDependentBean(dep, beanName);try{getBean(dep);}catch(NoSuchBeanDefinitionException ex) {thrownewBeanCreationException(mbd.getResourceDescription(), beanName,"'"+ beanName +"' depends on missing bean '"+ dep +"'", ex);}}}// Create bean instance.// 是否是单例的if(mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try{returncreateBean(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);throwex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}elseif(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);}else{String scopeName = mbd.getScope();finalScope scope =this.scopes.get(scopeName);if(scope ==null) {thrownewIllegalStateException("No Scope registered for scope name '"+ scopeName +"'");}try{Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try{returncreateBean(beanName, mbd, args);}finally{afterPrototypeCreation(beanName);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch(IllegalStateException ex) {thrownewBeanCreationException(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);throwex;}}// Check if required type matches the type of the actual bean instance.if(requiredType !=null&& !requiredType.isInstance(bean)) {try{T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if(convertedBean ==null) {thrownewBeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}returnconvertedBean;}catch(TypeMismatchException ex) {if(logger.isTraceEnabled()) {logger.trace("Failed to convert bean '"+ name +"' to required type '"+ClassUtils.getQualifiedName(requiredType) +"'", ex);}thrownewBeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return(T) bean;}

getSingleton

/** * Return the (raw) singleton object registered under the given name, * creating and registering a new one if none registered yet. *@parambeanName the name of the bean *@paramsingletonFactory the ObjectFactory to lazily create the singleton * with, if necessary *@returnthe registered singleton object */publicObjectgetSingleton(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) {if(this.singletonsCurrentlyInDestruction) {thrownewBeanCreationNotAllowedException(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 +"'");}beforeSingletonCreation(beanName);booleannewSingleton =false;booleanrecordSuppressedExceptions = (this.suppressedExceptions ==null);if(recordSuppressedExceptions) {this.suppressedExceptions =newLinkedHashSet<>();}try{// 实际上就是调用了CreateBeansingletonObject = 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) {throwex;}}catch(BeanCreationException ex) {if(recordSuppressedExceptions) {for(Exception suppressedException :this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throwex;}finally{if(recordSuppressedExceptions) {this.suppressedExceptions =null;}afterSingletonCreation(beanName);}if(newSingleton) {addSingleton(beanName, singletonObject);}}returnsingletonObject;}}

doCreateBean => 通过上方法的singletonObject = singletonFactory.getObject();进入的

/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@codepostProcessBeforeInstantiation} callbacks. *

Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. *@parambeanName the name of the bean *@parammbd the merged bean definition for the bean *@paramargs explicit arguments to use for constructor or factory method invocation *@returna new instance of the bean *@throwsBeanCreationException if the bean could not be created *@see#instantiateBean *@see#instantiateUsingFactoryMethod *@see#autowireConstructor */protectedObjectdoCreateBean(finalString beanName,finalRootBeanDefinition mbd,final@NullableObject[] args)throwsBeanCreationException{// Instantiate the bean.BeanWrapper instanceWrapper =null;if(mbd.isSingleton()) {instanceWrapper =this.factoryBeanInstanceCache.remove(beanName);}if(instanceWrapper ==null) {/**

    * 核心的创建实例化Bean的过程

    **/instanceWrapper = createBeanInstance(beanName, mbd, args);}finalObject 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);}catch(Throwable ex) {thrownewBeanCreationException(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.booleanearlySingletonExposure = (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));}// Initialize the bean instance.Object exposedObject = bean;try{/**

    * 填充属性,上文的实例化只是默认属性值。填充属性是初始化的第一步,第二步是执行init方法

    **/populateBean(beanName, mbd, instanceWrapper);/**

* 执行init方法

**/exposedObject = initializeBean(beanName, exposedObject, mbd);}catch(Throwable ex) {if(exinstanceofBeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw(BeanCreationException) ex;}else{thrownewBeanCreationException(mbd.getResourceDescription(), beanName,"Initialization of bean failed", ex);}}if(earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName,false);if(earlySingletonReference !=null) {if(exposedObject == bean) {exposedObject = earlySingletonReference;}elseif(!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set actualDependentBeans =newLinkedHashSet<>(dependentBeans.length);for(String dependentBean : dependentBeans) {if(!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if(!actualDependentBeans.isEmpty()) {thrownewBeanCurrentlyInCreationException(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{/**

    * 需要销毁的时候,销毁的钩子函数

    **/registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch(BeanDefinitionValidationException ex) {thrownewBeanCreationException(mbd.getResourceDescription(), beanName,"Invalid destruction signature", ex);}returnexposedObject;}

面试题:为甚么循环依赖的解决要使用三级缓存?

createBeanInstance => 核心的创建和实例化bean的过程,由doCreateBean调用

大量的反射出现在该方法中,用来创建对象

/** * Create a new instance for the specified bean, using an appropriate instantiation strategy: * factory method, constructor autowiring, or simple instantiation. *@parambeanName the name of the bean *@parammbd the bean definition for the bean *@paramargs explicit arguments to use for constructor or factory method invocation *@returna BeanWrapper for the new instance *@see#obtainFromSupplier *@see#instantiateUsingFactoryMethod *@see#autowireConstructor *@see#instantiateBean */protectedBeanWrappercreateBeanInstance(String beanName, RootBeanDefinition mbd,@NullableObject[] 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()) {thrownewBeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: "+ beanClass.getName());}Supplier instanceSupplier = mbd.getInstanceSupplier();if(instanceSupplier !=null) {returnobtainFromSupplier(instanceSupplier, beanName);}if(mbd.getFactoryMethodName() !=null) {returninstantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...booleanresolved =false;booleanautowireNecessary =false;if(args ==null) {synchronized(mbd.constructorArgumentLock) {if(mbd.resolvedConstructorOrFactoryMethod !=null) {resolved =true;autowireNecessary = mbd.constructorArgumentsResolved;}}}if(resolved) {if(autowireNecessary) {returnautowireConstructor(beanName, mbd,null,null);}else{returninstantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?// 构造器Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if(ctors !=null|| mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {returnautowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?ctors = mbd.getPreferredConstructors();if(ctors !=null) {returnautowireConstructor(beanName, mbd, ctors,null);}// No special handling: simply use no-arg constructor./**

* 默认无参构造

**/returninstantiateBean(beanName, mbd);}

instantiateBean(beanName, mbd) => 默认无参构造

/** * Instantiate the given bean using its default constructor. *@parambeanName the name of the bean *@parammbd the bean definition for the bean *@returna BeanWrapper for the new instance */protectedBeanWrapperinstantiateBean(finalString beanName,finalRootBeanDefinition mbd){try{Object beanInstance;finalBeanFactory parent =this;if(System.getSecurityManager() !=null) {beanInstance = AccessController.doPrivileged((PrivilegedAction) () ->// 实例化只会分配内存空间,设置默认值getInstantiationStrategy().instantiate(mbd, beanName, parent),getAccessControlContext());}else{beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);}BeanWrapper bw =newBeanWrapperImpl(beanInstance);initBeanWrapper(bw);returnbw;}catch(Throwable ex) {thrownewBeanCreationException(mbd.getResourceDescription(), beanName,"Instantiation of bean failed", ex);}}

instantiate

@OverridepublicObjectinstantiate(RootBeanDefinition bd,@NullableString beanName, BeanFactory owner){// Don't override the class with CGLIB if no overrides.if(!bd.hasMethodOverrides()) {Constructor constructorToUse;synchronized(bd.constructorArgumentLock) {constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;if(constructorToUse ==null) {finalClass clazz = bd.getBeanClass();if(clazz.isInterface()) {thrownewBeanInstantiationException(clazz,"Specified class is an interface");}try{if(System.getSecurityManager() !=null) {constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction>) clazz::getDeclaredConstructor);}else{constructorToUse = clazz.getDeclaredConstructor();}bd.resolvedConstructorOrFactoryMethod = constructorToUse;}catch(Throwable ex) {thrownewBeanInstantiationException(clazz,"No default constructor found", ex);}}}returnBeanUtils.instantiateClass(constructorToUse);}else{// Must generate CGLIB subclass.returninstantiateWithMethodInjection(bd, beanName, owner);}}

BeanUtils.instantiateClass => 通过构造器反射创建bean

/** * Convenience method to instantiate a class using the given constructor. *

Note that this method tries to set the constructor accessible if given a * non-accessible (that is, non-public) constructor, and supports Kotlin classes * with optional parameters and default values. *@paramctor the constructor to instantiate *@paramargs the constructor arguments to apply (use {@codenull} for an unspecified * parameter, Kotlin optional parameters and Java primitive types are supported) *@returnthe new instance *@throwsBeanInstantiationException if the bean cannot be instantiated *@seeConstructor#newInstance */publicstaticTinstantiateClass(Constructor<T> ctor, Object... args)throwsBeanInstantiationException{Assert.notNull(ctor,"Constructor must not be null");try{ReflectionUtils.makeAccessible(ctor);if(KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {returnKotlinDelegate.instantiateClass(ctor, args);}else{Class[] parameterTypes = ctor.getParameterTypes();Assert.isTrue(args.length <= parameterTypes.length,"Can't specify more arguments than constructor parameters");Object[] argsWithDefaultValues =newObject[args.length];for(inti =0; i < args.length; i++) {if(args[i] ==null) {Class parameterType = parameterTypes[i];argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) :null);}else{argsWithDefaultValues[i] = args[i];}}returnctor.newInstance(argsWithDefaultValues);}}catch(InstantiationException ex) {thrownewBeanInstantiationException(ctor,"Is it an abstract class?", ex);}catch(IllegalAccessException ex) {thrownewBeanInstantiationException(ctor,"Is the constructor accessible?", ex);}catch(IllegalArgumentException ex) {thrownewBeanInstantiationException(ctor,"Illegal arguments for constructor", ex);}catch(InvocationTargetException ex) {thrownewBeanInstantiationException(ctor,"Constructor threw exception", ex.getTargetException());}}

方法12:finishRefresh() => 完成刷新

/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@linkorg.springframework.context.event.ContextRefreshedEvent}. */protectedvoidfinishRefresh(){// Clear context-level resource caches (such as ASM metadata from scanning).// clearResourceCaches();// Initialize lifecycle processor for this context.initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(newContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);}

方法13:resetCommonCaches() => 缓存重置

/** * Reset Spring's common reflection metadata caches, in particular the * {@linkReflectionUtils}, {@linkAnnotationUtils}, {@linkResolvableType} * and {@linkCachedIntrospectionResults} caches. *@since4.2 *@seeReflectionUtils#clearCache() *@seeAnnotationUtils#clearCache() *@seeResolvableType#clearCache() *@seeCachedIntrospectionResults#clearClassLoader(ClassLoader) */protectedvoidresetCommonCaches(){ReflectionUtils.clearCache();AnnotationUtils.clearCache();ResolvableType.clearCache();CachedIntrospectionResults.clearClassLoader(getClassLoader());}

亚马逊测评 www.yisuping.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272