AbstractApplicationContext.refresh
为 Spring IOC
容器启动整个逻辑。refresh刷新意味Spring 可以在运行时刷新 BeanFactory
,那么我们不需要重启应用去更新容器。
@Override public void refresh() throws BeansException, IllegalStateException { //1、加锁避免同时关闭或者启动以及线程安全问题 synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. 准备刷新 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(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. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } } 复制代码
PropertySource
刷新前的准备,设置以及 active
状态,最重要的是 初始化 PropertySource
(子类按需初始化一些属性值),然后 校验必须的配置属性时可以解析的 。
通知子类刷新 Beanfactory
并获取刷新后的,子类分两种实现一种是每次刷新重新创建 Beanfactory
,还有一种是不做任何处理仅仅只设置下状态,分别对应可刷新刷新下文- AbstractRefreshableApplicationContext
和 GenericApplicationContext
.
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //刷新Beanfactory refreshBeanFactory(); //返回当前BeanFactory return getBeanFactory(); } 复制代码
GenericApplicationContext
与为每次刷新创建新的内部 BeanFactory
实例的其他 ApplicationContext
实现相比,此上下文的内部 BeanFactory
从一开始就可用,以便能够在其上注册 BeanDefinition 。 refresh()
只能被调用一次 。内嵌的 BeanFactory
是 DefaultListableBeanFactory
。
@Override protected final void refreshBeanFactory() throws IllegalStateException { if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } this.beanFactory.setSerializationId(getId()); } //内嵌的BeanFactory private final DefaultListableBeanFactory beanFactory; 复制代码
AbstractRefreshableApplicationContext
每次刷新都会创建创建一个 BeanFactory
。注意重新重新创建 BeanFactory
为** DefaultListableBeanFactory
**!!!
//刷新BeanFactory protected final void refreshBeanFactory() throws BeansException { //存在则销毁 if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { //创建新beanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //配置`Beanfactory` customizeBeanFactory(beanFactory); //BeanDefinition loadBeanDefinitions(beanFactory); //更新引用 this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } 复制代码
判断 Beanfactory
是否存在,存在则销毁Bean和关闭 Beanfactory
创建新的 Beanfactory
实际上是创建** DefaultListableBeanFactory
**,参数是获取当前 ParentBeanFactory
,Spring IOC 的层次获取Bean
protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); } 复制代码
配置 Beanfactory
配置了是否允许Beandefinition重写和是否允许循环引用
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } } 复制代码
加载 BeanDefinition
最重要的一步,根据不同子类(不同的 ApplicationContext
)读取Bean的配置元数据以加载 BeanDefinition
,钩子函数同于创建 BeanFactory
后根据不同应用上下去加载 BeanDefinitions
。加载的 BeanDefinition
注册进( registerBeanDefinition
) beanDefinitionMap
( ConcurrentHashMap
)根据元数据配置类型主要分以下4中:
/** * Load bean definitions into the given bean factory, typically through * delegating to one or more bean definition readers. */ protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException; //DefaultListableBeanFactory private final MapbeanDefinitionMap = new ConcurrentHashMap<>(256); 复制代码
AbstractXmlApplicationContext
:基于XMl配置元数据的上下文,针对不同类型的路径有
FileSystemXmlApplicationContext
:文件系统中XML配置
ClassPathXmlApplicationContext
:classPath下XMl配置
AnnotationConfigWebApplicationContext
:基于Java注解的配置元数据,也是最常用的。
GroovyWebApplicationContext
:基于Groovy的Web上下文
XmlWebApplicationContext
:基于XML的web上下文
配置BeanFactory中一些 标准配置 也是基础配置,如注册环境相关的Bean、 ApplicationContextAwareProcessor
等等。
还有排除一些 Aware
接口的自动装配因为一些 Aware
接口中的方法是 setxxx
开头,所以需要排除。
用于在 Beanfactory
创建 后的 回调 ,可能需要根据**不同应用上下文(即不同的子类)**对创建后的 Beanfactory
进行设置。此时 BeanDefinition
已经加载完毕,但是bean还未创建,这允许在某些 ApplicationContext 实现中注册特殊的 BeanPostProcessors
等
Spring 预留的扩展点, BeanFactoryPostProcessor
允许我们对已经 加载的 BeanDefinition
进行修改或者添加新的BeanDefinition 。非常重要的 扩展点 ,例如:
(1)配置类解析- ConfigurationClassPostProcessor
ConfigurationClassPostProcessor
完成配置类解析和注册像 @ComponentScan
、 @Import
、 @Bean
、 @ImportSource
导入xml配置文件、 @PropertySource
-导入properties文件、 ImportSelector
(Spring Boot的自动装配就是注册一个 ImportSelector
)等等这些功能都是在这里实现的。以下为配置解析的代码:
protected final SourceClass doProcessConfigurationClass( ConfigurationClass configClass, SourceClass sourceClass, Predicatefilter) throws IOException { if (configClass.getMetadata().isAnnotated(Component.class.getName())) { // Recursively process any member (nested) classes first processMemberClasses(configClass, sourceClass, filter); } // Process any @PropertySource annotations 解析@PropertySource for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } //省略日志打印 } // Process any @ComponentScan annotations 组件扫描 Set componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { for (AnnotationAttributes componentScan : componentScans) { // The config class is annotated with @ComponentScan -> perform the scan immediately Set scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // Check the set of scanned definitions for any further config classes and parse recursively if needed for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } // Process any @Import annotations @Import注解 processImports(configClass, sourceClass, getImports(sourceClass), filter, true); // Process any @ImportResource annotations @ImportResource导入的xml配置文件 AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); if (importResource != null) { String[] resources = importResource.getStringArray("locations"); Class extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); for (String resource : resources) { String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } // Process individual @Bean methods @Bean方法 Set beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // Process default methods on interfaces processInterfaces(configClass, sourceClass); // Process superclass, if any if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse return sourceClass.getSuperClass(); } } // No superclass -> processing is complete return null; } 复制代码
(2)BeanFactory后置处理器的SPI 扩展: BeanDefinitionRegistryPostProcessor
对标准 BeanFactoryPostProcessor
SPI 扩展,允许在常规 BeanFactoryPostProcessor
检测开始之前注册进一步的 bean 定义。特别是, BeanDefinitionRegistryPostProcessor
可以注册进一步的 bean 定义,这些定义反过来定义 BeanFactoryPostProcessor 实例。
BeanPostProcessor
是在Bean 初始化前后 触发进行扩展,所以在实例化bean之前需要注册 BeanPostProcessor
(完成Bean后置器的初始化)。
初始化消息资源例如 i18n(国际化)
初始化事件广播器以广播事件。 默认情况 下是 SimpleApplicationEventMulticaster
且所有侦听器都在 调用线程 中调用。这允许恶意侦听器阻塞整个应用程序的危险,但增加了最小的开销。可以指定一个替代任务执行器,让侦听器在不同的线程中执行,例如从线程池中执行。 所以利用Spring事件机制来初始化一个资源的适合建议不要太久(因为会阻塞刷新流程) 。
ps:之前犯过一个错误,由于 HDFSClient
在初始化的时候一旦连不上就会不断重试非常耗时(而且不会错误提示),而这个初始化逻辑是放在 @PostConstruct
导致本地在测试其他代码的时候启动巨慢,所以改成事件机制在收到 ContextRefreshedEvent
后初始化,但是发现还是很慢,然后才发现默认情况下是由刷新线程的来广播的。所以之后改成线程池了。
钩子函数表示Beanfactory正在刷新中,用于在实例化单例Bean 之前 处理化一些特殊的Bean。允许 子类 处理一些 特殊的Bean的初始化 。
注册监听器相关的Bean,用于处理广播器中的事件
BeanFactory初始化-实例化 所有 的 单例非延迟加载 的Bean。Bean生命周期也体现在里面。实际上所有Bean的创建**都是通过 getBean
**去创建的。
//DefaultListableBeanFactory类中 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. 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. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 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. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); } 复制代码
(1)初始化所有非懒加载的单例Bean
在 DefaultListableBeanFactory
中(也就是创建 BeanFactory
)中实现了该方法。遍历所有的Bean名称 通过 getBean
方法去创建哪些 单例非懒加载 的Bean。
@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. ListbeanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... 遍历所有的beanName for (String beanName : beanNames) { //获取合并的BeanDefinition MergedBeanDefinition??? RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //是单例非懒加载非抽象 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { //先尝试获取其FactoryBean Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean> factory = (FactoryBean>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction ) ((SmartFactoryBean>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean>) factory).isEagerInit()); } //如果是优先innit?? if (isEagerInit) { getBean(beanName); } } } else { //非FactoryBean直接创建Bean getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... 触发特殊的后置SmartInitializingSingleton for (String beanName : beanNames) { //从单例池种获取 Object singletonInstance = getSingleton(beanName); //如果是SmartInitializingSingleton 则执行后置 if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
doGetBean
-获取Bean
大体是先从缓存中获取,获取不到再判断是否交给父BeanFactory去获取,再根据不同的 Scope 从不同的地方获取Bean,获取不到则创建新的Bean(createBean方法),当然前提时 BeanDefinition
存在。
单例
先getSingleton(缓存),获取不到则创建
原型
直接CreateBean
其他
先从对应 Scope
中获取,获取不到则createBean
//AbstractBeanFactory中的getBean方法都是直接去创建Bean public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } protectedT doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //转化Bean名称 例如Bean的别名 FactoryBean的前缀等等 String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. 获取单例Bean Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //日志省略 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 原型循环依赖无法处理 原型Bean没有缓存因为每次获取都是新的 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 双亲委派模型 当当前上下文不存在BeanDefinition交给父BeanFactory去创建 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) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } //以上是类型检查(是否存在) if (!typeCheckOnly) { //标记Bean已经创建 markBeanAsCreated(beanName); } try { //获取合并的BeanDefinition 合并为什么 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); //创建其前置Bean(dependsOn) 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); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. 是单例 if (mbd.isSingleton()) { //从缓存获取 获取不到则创建Bean sharedInstance = getSingleton(beanName, () -> { try { 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); } //原型Bean 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); } else { //其他Scope 从对应的Scope中获取,获取不到在创建 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); } }); 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; } } // 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) { 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; 复制代码
刷新完成,发布Beanfactory创建完成事件
protected void finishRefresh() { // 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(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); } 复制代码
大体生命周期可分为4大步骤: 实例化(1)、属性填充(2)、初始化(3
16)、销毁(17 19)
,具体的生命周期如下:
创建时:
Bean实例化
填充属性值
BeanNameAware
的 setBeanName
BeanClassLoaderAware
的 setBeanClassLoader
BeanFactoryAware
的 setBeanFactory
EnvironmentAware
的 setEnvironment
EmbeddedValueResolverAware
的 setEmbeddedValueResolver
ResourceLoaderAware
的 setResourceLoader
(仅在在应用程序上下文中运行时适用)
ApplicationEventPublisherAware
的 setApplicationEventPublisher
(仅适用于在应用程序上下文中运行的情况)
MessageSourceAware
的 setMessageSource
(仅适用于在应用程序上下文中运行的情况)
ApplicationContextAware
的 setApplicationContext
(仅适用于在应用程序上下文中运行的情况)
ServletContextAware
的 setServletContext
(仅适用于在Web应用程序上下文中运行的情况)
BeanPostProcessors
的 postProcessBeforeInitialization
:bean后置处理器的前置处理
这里面还有对@PostConstruct注解的处理
InitializingBean
的 afterPropertiesSet
自定义的初始化方法
BeanPostProcessors
的 postProcessAfterInitialization
:bean后置处理器的后置处理
在关闭bean工厂时,以下生命周期方法:
DestructionAwareBeanPostProcessors
的 postProcessBeforeDestruction
方法
例如@PreDestroy
DisposableBean
的 destroy
方法
自定义销毁方法
根据源码定位到 Bean
的创建代码为 AbstractAutowireCapableBeanFactory.createBean
。
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException { 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> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); }//异常处理 try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //1、一些特殊Bean后置处理器的前置处理 在实例化前调用 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } }//异常处理 try { //实际创建Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }//异常处理 } //正常创建Bean的具体逻辑 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //2、(1)创建实例 instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. //3、执行MergedBeanDefinitionPostProcessor后置处理器 在初始化之前 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. 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)); } // Initialize the bean instance. Object exposedObject = bean; try { //4、注入Bean populateBean(beanName, mbd, instanceWrapper); //5、初始化Bean exposedObject = initializeBean(beanName, exposedObject, mbd); }//异常处理 //早期暴露 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); SetactualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { //抛出异常 } } } } // Register bean as disposable(一次性的). try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } 复制代码
创建Bean实例,实例化可分为三大部分:
实例化前置处理
InstantiationAwareBeanPostProcessor
添加实例化前回调的 BeanPostProcessor
子接口,以及实例化后但在设置显式属性或发生自动装配之前的回调(在 populateBean
中调用)。
创建实例
使用对应的实例化策略(即三种实例bean的方式)进行实例化
实例化后置处理
即 MergedBeanDefinitionPostProcessor
允许在bean实例化合并一些元数据到 BeanDefinition
当中,例如依赖注入的元数据就是在此处解析的。
1.1 resolveBeforeInstantiation 创建前置处理
在实例化前的后置处理器,处理一些实例化前的** Aware
**。根据源码是执行 InstantiationAwareBeanPostProcessor
相关的后置处理器。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. //如果不是合成的 ??? 并且有实例化前的Aware BeanPostProcessor if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; } //调用实例化前的BeanPostProcessor-InstantiationAwareBeanPostProcessor protected Object applyBeanPostProcessorsBeforeInstantiation(Class> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { // if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; } 复制代码
1.2 createBeanInstance创建Bean
根据 BeanDefinition
的配置调用不同的 实例化策略 进行实例化。本质上就是那三种bean的实例化方式- InstantiationStrategy
构造函数
静态工厂
实例工厂
外部实例
例如在外面实例化,再利用 SingletonBeanRegistry
注册到容器中
//实例化策略 public interface InstantiationStrategy { //直接在此工厂中返回具有给定名称的 bean 实例。有些bean是在外部实例化后注册进来的 Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) throws BeansException; //构造函数 Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, Constructor> ctor, Object... args) throws BeansException; //静态工厂或者实例工厂 Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @Nullable Object factoryBean, Method factoryMethod, Object... args) throws BeansException; } //源码 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); //非pubic的类无法构建 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... 重新构建一个相同的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); } } // Candidate constructors for autowiring? 构造器自动装配 Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction? 有优选选择的构造器 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } //没有特殊出路就是调用无参的构造器 // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); } 复制代码
1.3 applyMergedBeanDefinitionPostProcessors-实例化后置处理
执行 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
运行时 合并bean 定义 的后处理器回调接口。例如下面两个将一些运行时的元数据解析合并到beanDefinition中。例如 基于注解依赖注入的元数据 就是在此解析后加入到 BeanDefinition
当中。
CommonAnnotationBeanPostProcessor
处理Java @Resource
、 @PostConstruct
、 @PreDestroy
等元数据
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) { super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName); InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } 复制代码
AutowiredAnnotationBeanPostProcessor
@Autowire
注解注入依赖逻辑,找到@Autowire对应的注入信息。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } 复制代码
populateBean
填充Bean属性(依赖注入和自动装配)完成 自动装配 (包含三个注解自动装配)。使用Bean定义中的属性值填充给定的 BeanWrapper
中的Bean实例,包含自动装配( BeanDefinition
中 autowire
) 且执行了 InstantiationAwareBeanPostProcessor
后置处理器(特殊的后置器)的 postProcessAfterInstantiation
和 postProcessPropertyValues
,在 postProcessPropertyValues
中进行了 注解方式的@Resource、@Value、@Autowire的自动装配 等操作。
ps:这里 只关注了自动装配 ,可能有其他功能实现。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //null值出力 //2.1实例化后置处理 // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); //2.2 自动装配 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } } 复制代码
2.1 实例化后置处理器 InstantiationAwareBeanPostProcessor
在实例化前置的处理时,提到过这个接口,这里就是 实例化后但在设置显式属性或发生自动装配之前的回调 。
2.1.1注解方式的注入
基于 注解形式 的 依赖注入 的都是在此实现的(也是 注解方式的自动装配 ),原理是 反射调用 设置字段值。。
2.1.1.1 处理 @Value
和@ Autowire
AutowiredAnnotationBeanPostProcessor
处理 @Value
和@ Autowire
注解,根据bean的 InjectionMetadata
进行注入。具体实现方式通过 反射 设置字段值。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { //获取注入元数据 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { //进行注入 metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; } protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { //主要处理的字段 Field field = (Field) this.member; Object value; //解析需要注入值 if (this.cached) { try { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } catch (NoSuchBeanDefinitionException ex) { // Unexpected removal of target bean for cached argument -> re-resolve value = resolveFieldValue(field, bean, beanName); } } else { value = resolveFieldValue(field, bean, beanName); } //反射设置值 if (value != null) { ReflectionUtils.makeAccessible(field); field.set(bean, value); } } 复制代码
2.1.1.2处理 @Resource
CommonAnnotationBeanPostProcessor
处理Java @Resource
注解,实现方式和上节 AutowiredAnnotationBeanPostProcessor
类似,只不过在解析注入元数据不一样。
2.2 自动装配
Spring支持5种自动装配分别如下:
//AutowireCapableBeanFactory //不自动装配 int AUTOWIRE_NO = 0; //按名字自动装配 int AUTOWIRE_BY_NAME = 1; //按类型自动装配 int AUTOWIRE_BY_TYPE = 2; //按构造器自动装配 int AUTOWIRE_CONSTRUCTOR = 3; //自动探测 就是混合自动装配 已经启用更推荐使用注解形式 @Deprecated int AUTOWIRE_AUTODETECT = 4; 复制代码
自动装配使用方法就是设置 BeanDefinition
的自动装配属性,例如
复制代码
Bean大部分生命周期都在此。分为四大部分:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
3.1 执行Aware接口
Aware
感知到需要的资源已经准备好,可以直接获取。执行顺序如下
private void invokeAwareMethods(String beanName, 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); } } } 复制代码
执行Bean后置处理器的 postProcessBeforeInitialization
即特殊的初始化前处理。 ApplicationContextAwareProcessor
后置处理器 它暴露了很多Aware接结口Aware设置顺序如下:
private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } } 复制代码
ImportAware
ImportAwareBeanPostProcessor
处理** ImportAware
**接口。即针对于使用 @Import
导入bean时,bean通过该接口可以拿到 Import
元数据。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) { if (bean instanceof ImportAware) { ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class); AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName()); if (importingClass != null) { ((ImportAware) bean).setImportMetadata(importingClass); } } return bean; } 复制代码
3.2 Bena后置处理器的初始化前置处理方法
执行初始化的前置处理
3.2.1 @PostConstruct
CommonAnnotationBeanPostProcessor
在 postProcessBeforeInitialization
去 执行 @PostConstruct
指定的初始化方法 。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; } public void invokeInitMethods(Object target, String beanName) throws Throwable { CollectioncheckedInitMethods = this.checkedInitMethods; Collection initMethodsToIterate = (checkedInitMethods != null ? checkedInitMethods : this.initMethods); if (!initMethodsToIterate.isEmpty()) { for (LifecycleElement element : initMethodsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod()); } element.invoke(target); } } } 复制代码
3.3 invokeInitMethods-执行初始化方法
Bean的指定的一些初始化方法,执行顺序如下:
3.3.1 InitializingBean.afterPropertiesSet
实现了 InitializingBean
接口
3.3.2 invokeCustomInitMethod
-自定义初始化方法
用户指定的触发化方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); //如果实现InitializingBean接口 则执行afterPropertiesSet方法 if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction
3.4 Bean后置处理器的初始化后置处理方法
初始化后的后置处理,执行Bean后置处理器的 postProcessAfterInitialization
。例如AOP代理对象的生成就是通过Bean后置处理的初始化后置处理完成的
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } //AOP代理对象生成 AbstractAutoProxyCreator代码片段 public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } 复制代码
销毁和初始化差不多,每个Bean在创建时都会创建一个 DisposableBeanAdapter
用于销毁Bean执行顺序如下:
4.1 postProcessBeforeDestruction
: @PreDestroy
利用 CommonAnnotationBeanPostProcessor
继承了 InitDestroyAnnotationBeanPostProcessor
在 postProcessBeforeDestruction
中执行了 @PreDestroy
指定的销毁方法
@Override public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeDestroyMethods(bean, beanName); } catch (InvocationTargetException ex) { String msg = "Destroy method on bean with name '" + beanName + "' threw an exception"; if (logger.isDebugEnabled()) { logger.warn(msg, ex.getTargetException()); } else { logger.warn(msg + ": " + ex.getTargetException()); } } catch (Throwable ex) { logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex); } 复制代码
4.2 DisposableBean.destroy
bean实现 DisposableBean
即可时在销毁时执行 destroy()
方法
4.3 invokeCustomDestroyMethod
-自定义销毁方法
用户指定的销毁方法
@Override public void destroyBean(Object existingBean) { new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy(); } public void destroy() { //1、postProcessBeforeDestruction if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { //执行销毁Aware相关的后置处理器的postProcessBeforeDestruction for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } } //2、DisposableBean if (this.invokeDisposableBean) { //日志打印 try { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction
根据上节的源码分析,Beanfactory初始化( finishBeanFactoryInitialization
)时会创建 非懒加载单例 Bean,且由 getBean
方法去创建一个Bean。所以对于 懒加载 的Bean也是由** getBean
**获取,依赖注入也是在Bean后置处理器中通过 getBean
去获取依赖的Bean。在 doGetBean
( getBean
调用)中如果Bean不存在会创建一个新的Bean( createBean
)。 所以一个懒加载被一个非拦截加载的Bean所依赖,此时拦截bean还是会在启动流程中实例化 。
循环依赖是指两个Bean之间互相依赖的导致循环创建问题。Spring提供了三级缓存来解决循环依赖问题。由于Bean生命周期 很长 ,所以可以调用构造器后立即 暴露引用 (放入缓冲中,下次获取则直接从缓存中获取)那么不需要等Bean完全初始化便可使用。
首先对于 原型Bean的循环依赖 是无法解决的,因为原型Bean每次获取都是创建新Bean是不能放入缓存中的。其次 构造器注入 的循环依赖无法解决,因为无法先构造而。
对应单例Bean ,Spring在 getBean
时先尝试从缓存中获取,获取不到再去 createBean
。根据源码我们可以看到缓存分三级,依次从这些缓存中获取。
public Object getSingleton(String beanName) { return getSingleton(beanName, true); } @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { //从一级缓存中获取 Object singletonObject = this.singletonObjects.get(beanName); //如果一级缓存中没有且单例Bean是在创建中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //从二级缓存中获取 singletonObject = this.earlySingletonObjects.get(beanName); //二级缓存中没有 且允许提前使用引用 if (singletonObject == null && allowEarlyReference) { //从三级缓存中获取 ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //获得Bean 引用 singletonObject = singletonFactory.getObject(); //升级到二级缓存 this.earlySingletonObjects.put(beanName, singletonObject); //删除三级缓存 this.singletonFactories.remove(beanName); } } } } return singletonObject; } 复制代码
一级缓存中是 完整 的Bean实例,是直接可以使用的,也叫单例池。
//一级缓存 private final MapsingletonObjects = new ConcurrentHashMap<>(256); 复制代码
AbstractBeanFactory.doGetBean
中获取或者创建Bean,如果是新的 Bean
则加入一级缓存,于此 同时 会 删除 二、三级缓存。 createBean
方法完成意味着Bean走完了生命周期,此时的Bean是完整的。
// Create bean instance. if (mbd.isSingleton()) { // sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //创建新的Bean singletonFactory为上面lambda表达式即通过createBean创建新的 try { singletonObject = singletonFactory.getObject(); newSingleton = true; } //是新的Bean if (newSingleton) { addSingleton(beanName, singletonObject); } //加入一级缓存 protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } 复制代码
二级缓存存放的是 早期 的Bean(可能是非完整的bean), getSingleton
中会依次遍历这三级缓存,如果是在 三级缓存 中则通过对应的 ObjectFactory
(在此对)获得 Bean , 并升级到二级缓存 中。
复制代码
在创建Bean时如果发现是单例Bean且允许提前暴露引用则加入三级缓存。三级缓存存储的是Bean对应的** ObjectFactory
**即Bean的工厂,其逻辑是通过在 getObject
中调用 getEarlyBeanReference
(它是Spring预留的扩展点通过 SmartInstantiationAwareBeanPostProcessor
对其扩展)。三级缓存的目的是解决存在aop代理时提前触发代理对象的生成。
/** 三级缓存 Cache of singleton factories: bean name to ObjectFactory. */ private final Map> singletonFactories = new HashMap<>(16); //-------------------------------------------------------------- //doCreateBean方法中 在此代码块之前是创建Bean实例createBeanInstance方法, // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. //是单例且允许循环依赖引用以及当前Bean正在创建中则 表示可以提前暴露引用 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { //加入三级缓存 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } //加入三级缓存 protected void addSingletonFactory(String beanName, ObjectFactory> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); //注意synchronized synchronized (this.singletonObjects) { //线程安全所以看看其他有没有创建完成 if (!this.singletonObjects.containsKey(beanName)) { //加入三级缓存 this.singletonFactories.put(beanName, singletonFactory); //删除二级缓存 this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } } 复制代码
getEarlyBeanReference
getEarlyBeanReference
是Spring预留的 扩展点 -针对获取 Bean提前暴露的引用 的 一次性扩展 操作,通过 SmartInstantiationAwareBeanPostProcessor
后置处理器回调 getEarlyBeanReference
方法对其扩展。例如为了解决存在AOP时的循环依赖而提前触发AOP代理对象生成。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; } 复制代码
通过原理分析,一般情况我们只需要二级缓存即用另一个缓存提前暴露引用(构造后)便可解决循环依赖的问题,但是 Spring AOP会生成代理对象 也就是会修改引用是不能直接用提前暴露的引用的。利用三级缓存 预留扩展点 ,三级缓存获取时对暴露的Bean引用做 一次性 的处理-存在 AOP时是需要提前触发生成代理对象然后暴露出去 。因为代理对象的生成是在bean后置处理器中的后置处理完成的,而Bean属性填充等其他方式依赖其他Bean是在其前面的(也就是循环依赖是在前面),所以需要提前触发才能解决此循环依赖问题。