From b3393888085aafb1c97620793d9f826278762d64 Mon Sep 17 00:00:00 2001 From: youthlql <1826692270@qq.com> Date: Thu, 27 Jan 2022 21:57:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0Spring=E6=BA=90=E7=A0=81-?= =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 1 + .gitignore | 1 + README.md | 13 +- .../04.第4章-Bean初始化流程.md | 1338 +++++++++++++++++ 4 files changed, 1346 insertions(+), 7 deletions(-) create mode 100644 docs/spring-sourcecode-v1/04.第4章-Bean初始化流程.md diff --git a/.gitattributes b/.gitattributes index 2ab2d3c..2255dfe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,4 @@ *.js linguist-language=java *.css linguist-language=java *.html linguist-language=java + diff --git a/.gitignore b/.gitignore index 853f53d..dfe0d14 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ dataSources/ ### OS ### .DS_Store + diff --git a/README.md b/README.md index d82a3dc..7d92f9a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,6 @@ -> - 2022-01-21紧急:由于我所使用的图床暂时出了点问题,图片访问可能会有问题【没问题的话可以忽略这条消息】。批量替换比较麻烦,我想暂时等几天看看,官方没有恢复的话,我准备转移图床。如果有读者很急的话,可以访问图片源文件,我将所有的图片存到了网盘,将文章和图片下到本地然后放到对应的markdown文件夹下面,然后批量替换路径即可。 -> -> 阿里网盘:https://www.aliyundrive.com/s/43jcQbstUpX -> -> 百度网盘:https://pan.baidu.com/s/1fb-Rt7Hq7C8Zo82jLANnuQ 提取码:u4sf -> + > 1. 文章会优先发布在[Github](https://github.com/youthlql/JavaYouth),其它平台会晚一段时间,文章纠错与更新内容只在Github。如果Github很卡,可以在去[Gitee](https://gitee.com/youthlql/JavaYouth)克隆。 > 2. 提供两种在线阅读方式:[电子书在线阅读](https://imlql.cn/JavaYouth/#/),[个人博客](https://imlql.cn/)浏览。 @@ -143,7 +138,7 @@ -## 源码【01.01更新】 +## 源码【01.27更新】 @@ -153,6 +148,10 @@ [03.第3章-后置处理器和Bean生命周期](docs/spring-sourcecode-v1/03.第3章-后置处理器和Bean生命周期.md) +[04.第4章-Bean初始化流程](docs/spring-sourcecode-v1/04.第4章-Bean初始化流程.md) + + + # Netty ## 入门 diff --git a/docs/spring-sourcecode-v1/04.第4章-Bean初始化流程.md b/docs/spring-sourcecode-v1/04.第4章-Bean初始化流程.md new file mode 100644 index 0000000..7500040 --- /dev/null +++ b/docs/spring-sourcecode-v1/04.第4章-Bean初始化流程.md @@ -0,0 +1,1338 @@ +--- +title: Spring源码系列-第4章-Bean初始化流程 +tags: + - Spring源码 +categories: + - Spring + - 源码V1 +keywords: Spring,框架,spring源码 +description: 总结一下Bean的初始化 +cover: 'https://gitee.com/youthlql/randombg/raw/master/logo/spring.png' +abbrlink: 49f419ae +date: 2022-01-27 21:01:02 +--- + +# 第4章-Bean初始化流程 + +## 流程图-bean初始化流程 + + + +## AbstractApplicationContext#refresh() + +```java + @Override //容器刷新的十二大步。模板模式 + public void refresh() throws BeansException, IllegalStateException { + synchronized (this.startupShutdownMonitor) { + StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); + + // Prepare this context for refreshing. + prepareRefresh(); + + // Tell the subclass to refresh the internal bean factory. + // 工厂创建:BeanFactory第一次开始创建的时候,有xml解析逻辑。 + 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); + + StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); + //工厂增强:执行所有的BeanFactory后置增强器;利用BeanFactory后置增强器对工厂进行修改或者增强,配置类会在这里进行解析。 Invoke factory processors registered as beans in the context. + invokeBeanFactoryPostProcessors(beanFactory); + + //注册所有的Bean的后置处理器 Register bean processors that intercept bean creation. + registerBeanPostProcessors(beanFactory); + beanPostProcess.end(); + + // Initialize message source for this context. + initMessageSource(); + + // Initialize event multicaster for this context. + initApplicationEventMulticaster(); + + // Initialize other special beans in specific context subclasses. + onRefresh(); + + //注册监听器,从容器中获取所有的ApplicationListener; Check for listener beans and register them. + registerListeners(); + + // Instantiate all remaining (non-lazy-init) singletons. + //bean创建;完成 BeanFactory 初始化。(工厂里面所有的组件都好了) + 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(); + contextRefresh.end(); + } + } + } + + +``` + +## AbstractApplicationContext#finishBeanFactoryInitialization() + +```java + protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { + // 给工厂设置好 ConversionService【负责类型转换的组件服务】, 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 BeanFactoryPostProcessor + // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before: + // at this point, primarily for resolution in annotation attribute values. + if (!beanFactory.hasEmbeddedValueResolver()) { + beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); + } + + // LoadTimeWeaverAware;aspectj:加载时织入功能【aop】。 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. + //初始化所有的非懒加载的单实例Bean + beanFactory.preInstantiateSingletons(); + } +``` + + + + + +## DefaultListableBeanFactory#preInstantiateSingletons() + +```java + + String FACTORY_BEAN_PREFIX = "&"; + + public void preInstantiateSingletons() throws BeansException { + 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. + List beanNames = new ArrayList<>(this.beanDefinitionNames); + + // 创建出所有的单实例Bean;Trigger initialization of all non-lazy singleton beans... + for (String beanName : beanNames) { + RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinition + if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { + if (isFactoryBean(beanName)) { //如果是FactoryBean则执行下面逻辑 + Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //得到HelloFactory + 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()); + } + if (isEagerInit) { + getBean(beanName); + } + } + } + else { //不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建 + getBean(beanName); // + } + } + } + + // 触发 post-initialization 逻辑; Trigger post-initialization callback for all applicable beans... + for (String beanName : beanNames) { + Object singletonInstance = getSingleton(beanName); + if (singletonInstance instanceof SmartInitializingSingleton) { + StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize") + .tag("beanName", beanName); + SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; + if (System.getSecurityManager() != null) { + AccessController.doPrivileged((PrivilegedAction) () -> { + smartSingleton.afterSingletonsInstantiated(); + return null; + }, getAccessControlContext()); + } + else { + smartSingleton.afterSingletonsInstantiated(); + } + smartInitialize.end(); + } + } + } +``` + + + +## 工厂Bean的初始化方式 + + + + + + + +### AbstractBeanFactory#isFactoryBean() + +```java + public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException { + String beanName = transformedBeanName(name); + Object beanInstance = getSingleton(beanName, false); + if (beanInstance != null) { + return (beanInstance instanceof FactoryBean); + } + // No singleton instance found -> check bean definition. + if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { + // No bean definition found in this factory -> delegate to parent. + return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name); + } + return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName)); + } + + protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) { + Boolean result = mbd.isFactoryBean; + if (result == null) { + Class beanType = predictBeanType(beanName, mbd, FactoryBean.class); + result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType)); + mbd.isFactoryBean = result; + } + return result; + } +``` + + + +无论是不是工厂Bean,最后调用的都是`AbstractBeanFactory#getBean(String name)` + + + +### 测试类 + +由于工厂Bean只有在你getBean获取的时候,它才会创建,所以我们必须用这些测试类测试一下。 + +```java +public class AnnotationMainTest { + + public static void main(String[] args) { + + ApplicationContext applicationContext = + new AnnotationConfigApplicationContext(MainConfig.class); + Hello bean = applicationContext.getBean(Hello.class); + System.out.println(bean); + + } +} +``` + +**MainConfig** + +```java +@ComponentScan("cn.imlql.spring") +@Configuration +public class MainConfig { + + public MainConfig(){ + System.out.println("MainConfig...创建了...."); + } + +} +``` + + + +**HelloFactory** + +```java +@Component //也可以实现 SmartFactoryBean。指定提前加载 +public class HelloFactory implements FactoryBean { + + @Override + public Hello getObject() throws Exception { + return new Hello(); //这是最终获取到的对象 pos_1 + } + + @Override + public Class getObjectType() { + return Hello.class; + } +} +``` + +pos_1位置打个断点。 + +**Hello** + +```java +public class Hello { +} +``` + + + +### Debug调用栈 + +从这里开始看调用链 + + + + + + + + + + + + + +### DefaultListableBeanFactory#resolveBean() + +```java + @Nullable + private T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) { + NamedBeanHolder namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull); + if (namedBean != null) { + return namedBean.getBeanInstance(); + } + BeanFactory parent = getParentBeanFactory(); + if (parent instanceof DefaultListableBeanFactory) { + return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull); + } + else if (parent != null) { + ObjectProvider parentProvider = parent.getBeanProvider(requiredType); + if (args != null) { + return parentProvider.getObject(args); + } + else { + return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable()); + } + } + return null; + } + + + private NamedBeanHolder resolveNamedBean( + ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException { + + Assert.notNull(requiredType, "Required type must not be null"); + String[] candidateNames = getBeanNamesForType(requiredType); //按照类型获取组件 + + // ... + + if (candidateNames.length == 1) { + return resolveNamedBean(candidateNames[0], requiredType, args); + } + // ... + return null; + } + + +``` + +### DefaultListableBeanFactory#doGetBeanNamesForType() + +```java +//获取某一个组件在容器中的名字。 工厂Bean的主要逻辑还是走到这里,这里我们之前讲过 +private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) { + List result = new ArrayList<>(); + + // Check all bean definitions. 因为Spring没有直接保存class--bean名字的对应信息,只能遍历所有的beanname,拿出他们beanname的定义信息,再看是否我指定的类型。 + for (String beanName : this.beanDefinitionNames) { + // Only consider bean as eligible if the bean name is not defined as alias for some other bean. + if (!isAlias(beanName)) { //判断是否别名 + try { + RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); + // Only check bean definition if it is complete. + if (!mbd.isAbstract() && (allowEagerInit || + (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) && + !requiresEagerInitForType(mbd.getFactoryBeanName()))) { + boolean isFactoryBean = isFactoryBean(beanName, mbd); //是否FactoryBean + BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); + boolean matchFound = false; + boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName)); + boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit()); + if (!isFactoryBean) { + if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) { + matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); //是否类型匹配? + } + } + else { + if (includeNonSingletons || isNonLazyDecorated || + (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) { + matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); + } + if (!matchFound) { + // In case of FactoryBean, try to match FactoryBean instance itself next. + beanName = FACTORY_BEAN_PREFIX + beanName; + matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); + } + } + if (matchFound) { + result.add(beanName); + } + } + } + catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) { + if (allowEagerInit) { + throw ex; + } + // Probably a placeholder: let's ignore it for type matching purposes. + LogMessage message = (ex instanceof CannotLoadBeanClassException ? + LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) : + LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName)); + logger.trace(message, ex); + // Register exception, in case the bean was accidentally unresolvable. + onSuppressedException(ex); + } + catch (NoSuchBeanDefinitionException ex) { + // Bean definition got removed while we were iterating -> ignore. + } + } + } + + // Check manually registered singletons too. + for (String beanName : this.manualSingletonNames) { + try { + // In case of FactoryBean, match object created by FactoryBean. + if (isFactoryBean(beanName)) { + if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) { + result.add(beanName); + // Match found for this bean: do not match FactoryBean itself anymore. + continue; + } + // In case of FactoryBean, try to match FactoryBean itself next. + beanName = FACTORY_BEAN_PREFIX + beanName;//注意这里的工厂Bean前缀 + } + // Match raw bean instance (might be raw FactoryBean). + if (isTypeMatch(beanName, type)) { + result.add(beanName); + } + } + catch (NoSuchBeanDefinitionException ex) { + // Shouldn't happen - probably a result of circular reference resolution... + logger.trace(LogMessage.format( + "Failed to check manually registered singleton with name '%s'", beanName), ex); + } + } + + return StringUtils.toStringArray(result); +} +``` + +### BeanFactory + +```java +String FACTORY_BEAN_PREFIX = "&"; +``` + +1. 工厂Bean在Spring容器中一开始保存的是工厂本身,在这里就是HelloFactory +2. 第一次获取Hello组件的时候。doGetBeanNamesForType循环所有组件,找有没有一个beanName是Hello的组件 +3. 它在找的途中发现了HelloFactory这个工厂bean,于是就调用`HelloFactory#getObject()`,创建Hello这个bean + + + + + +最后返回 + + + + + + + + + + + + + +## Bean创建的前期 + +### 测试类 + +```java +@Component +public class Cat implements InitializingBean, SmartInitializingSingleton { + + public Cat(){ + System.out.println("cat被创建了..."); + } + + private String name; + + + @Value("${JAVA_HOME}") //自动赋值功能 + public void setName(String name) { + System.out.println("cat....setName正在赋值调用...."); + this.name = name; + } + //注解怎么定义这个是初始化方法? + public String getName() { + return name; + } + + @Override + public void afterPropertiesSet() throws Exception { + System.out.println("CatInitializingBean..afterPropertiesSet..."); + } + + @Override + public void afterSingletonsInstantiated() { + System.out.println("所有组件都创建完成以后,再来执行这个方法....."); + } +} +``` + +> 测试类基本都是大同小异的,这里不再给出全部的测试类,只给出这一小节用得到的。 + +我们以创建Cat这个Bean为例子来讲解。 + + + +### Debug调用栈 + + + + + + + +### AbstractBeanFactory#doGetBean() + +```java + protected T doGetBean( + String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) + throws BeansException { + + String beanName = transformedBeanName(name); //转换Bean名字 + Object beanInstance; + + // 先检查单实例bean的缓存 Eagerly check singleton cache for manually registered singletons. + 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 + "'"); + } + } + beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); + } + + else { //默认第一次获取组件都会进入else环节 + // Fail if we're already creating this bean instance: + // We're assumably within a circular reference. + if (isPrototypeCurrentlyInCreation(beanName)) { + throw new BeanCurrentlyInCreationException(beanName); + } + + // 拿到整个beanFactory的父工厂;看父工厂没有,从父工厂先尝试获取组件; Check if bean definition exists in this factory. + BeanFactory parentBeanFactory = getParentBeanFactory(); + if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { //以下开始从父工厂获取组件 + // Not found -> check parent. + // ... + } + + if (!typeCheckOnly) { + markBeanAsCreated(beanName); //标记当前beanName的bean已经被创建 + } + + StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") + .tag("beanName", name); + try { + if (requiredType != null) { + beanCreation.tag("beanType", requiredType::toString); + } + RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); + checkMergedBeanDefinition(mbd, beanName, args); + + // Guarantee initialization of beans that the current bean depends on. + String[] dependsOn = mbd.getDependsOn(); + if (dependsOn != null) { + for (String dep : dependsOn) { //看当前Bean有没有依赖其他Bean + if (isDependent(beanName, dep)) { + throw new BeanCreationException(mbd.getResourceDescription(), beanName, + "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); + } + registerDependentBean(dep, beanName); + try { + getBean(dep); //依赖了其他bean,就先获取其他的哪些bean + } + catch (NoSuchBeanDefinitionException ex) { + throw new BeanCreationException(mbd.getResourceDescription(), beanName, + "'" + beanName + "' depends on missing bean '" + dep + "'", ex); + } + } + } + + // 创建bean的实例;Create bean instance. + if (mbd.isSingleton()) { + sharedInstance = getSingleton(beanName, () -> { + try { + return createBean(beanName, mbd, args); //创建bean对象的实例 + } + 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是否是FactoryBean + beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); + } + else if (mbd.isPrototype()) { + // ... + } + else{} + // ... + //转Object为Bean的T类型 + return adaptBeanInstance(name, beanInstance, requiredType); + } + + + protected void markBeanAsCreated(String beanName) { + if (!this.alreadyCreated.contains(beanName)) { + synchronized (this.mergedBeanDefinitions) { + if (!this.alreadyCreated.contains(beanName)) { + // Let the bean definition get re-merged now that we're actually creating + // the bean... just in case some of its metadata changed in the meantime. + clearMergedBeanDefinition(beanName); + this.alreadyCreated.add(beanName); + } + } + } + } + + // 已经创建了的Bean名字池。Spring内部有很多这样记录Bean状态的集合(池子) + /** Names of beans that have already been created at least once. */ + private final Set alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); +``` + +#### DefaultSingletonBeanRegistry + +> ``` +> // 先检查单实例bean的缓存 Eagerly check singleton cache for manually registered singletons. +> Object sharedInstance = getSingleton(beanName); //检查缓存中有没有,如果是第一次获取肯定是没有的 +> ``` +> +> 接上面 + + + +```java + @Override + @Nullable + public Object getSingleton(String beanName) { + return getSingleton(beanName, true); + } + + //下面的代码是解决循环依赖的核心,后面细讲 + @Nullable + protected Object getSingleton(String beanName, boolean allowEarlyReference) { + //先检查单例缓存池,获取当前对象 Quick check for existing instance without full singleton lock + Object singletonObject = this.singletonObjects.get(beanName); //一级缓存 + if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //如果当前bean正在创建过程中,而且缓存中没有则继续 + singletonObject = this.earlySingletonObjects.get(beanName); //二级 + if (singletonObject == null && allowEarlyReference) { + synchronized (this.singletonObjects) { + // Consistent creation of early reference within full singleton lock + singletonObject = this.singletonObjects.get(beanName); + if (singletonObject == null) { + singletonObject = this.earlySingletonObjects.get(beanName); + if (singletonObject == null) { + ObjectFactory singletonFactory = this.singletonFactories.get(beanName); //三级 + if (singletonFactory != null) { + singletonObject = singletonFactory.getObject(); + this.earlySingletonObjects.put(beanName, singletonObject); + this.singletonFactories.remove(beanName); + } + } + } + } + } + } + return singletonObject; + } + + /** 享元模式的单例。缓存所有单实例对象,单例对象池。ioc容器-单例池; Cache of singleton objects: bean name to bean instance. */ + private final Map singletonObjects = new ConcurrentHashMap<>(256); + + // 正在创建的组件的名字池 + /** Names of beans that are currently in creation. */ + private final Set singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); + +``` + + + + + +### AbstractBeanFactory#doGetBean()创建Bean的核心代码 + +```java + // 创建bean的实例;Create bean instance. + if (mbd.isSingleton()) { + sharedInstance = getSingleton(beanName, () -> { + try { + return createBean(beanName, mbd, args); //创建bean对象的实例 + } + 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是否是FactoryBean + beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); + } +``` + +这里是创建Bean的核心,就是一个lamda表达式 + + + +### DefaultSingletonBeanRegistry#getSingleton() + +```java + 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) { //单实例池子里面没有当前对象(说明没有创建完成) + if (this.singletonsCurrentlyInDestruction) { + throw new BeanCreationNotAllowedException(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); //单实例创建之前 + boolean newSingleton = false; + boolean recordSuppressedExceptions = (this.suppressedExceptions == null); + if (recordSuppressedExceptions) { + this.suppressedExceptions = new LinkedHashSet<>(); + } + try { + /* + 1.这里会调用lamda表达式的内容,真正创建对象,也就是调用creatbean, + 2.ObjectFactory类注释上写了这里类似于一个工厂Bean,所以这里写的和工厂bean一样的getObject()。我们 + 在前面是这样讲的 + 3.但实际上ObjectFactory就是一个@FunctionalInterface标注的函数式接口,你调用它唯一的getObject(),那么 + 当然就会调用createbean了。(这里就涉及lamda表达式的知识了,不知道的建议自行补习) + */ + singletonObject = 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) { + throw ex; + } + } + catch (BeanCreationException ex) { + if (recordSuppressedExceptions) { + for (Exception suppressedException : this.suppressedExceptions) { + ex.addRelatedCause(suppressedException); + } + } + throw ex; + } + finally { + if (recordSuppressedExceptions) { + this.suppressedExceptions = null; + } + afterSingletonCreation(beanName); + } + if (newSingleton) { + addSingleton(beanName, singletonObject); + } + } + return singletonObject; + } + } + + + protected void beforeSingletonCreation(String beanName) { + // 创建之前判断将Bean加入singletonsCurrentlyInCreation这个set集合 + if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { + throw new BeanCurrentlyInCreationException(beanName); + } + } + + protected void afterSingletonCreation(String beanName) { + if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { + throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); + } + } + + 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); + } + } +``` + + + +### AbstractAutowireCapableBeanFactory#createBean() + +```java + @Override + 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; + + // 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(); + } + catch (BeanDefinitionValidationException ex) { + throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), + beanName, "Validation of method overrides failed", ex); + } + + try { + // 提前给我们一个机会,去返回组件的代理对象。 Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. + Object bean = resolveBeforeInstantiation(beanName, mbdToUse); + if (bean != null) { + return bean; + } + } + catch (Throwable ex) { + throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, + "BeanPostProcessor before instantiation of bean failed", ex); + } + + try { //Spring真正自己创建对象 + Object beanInstance = doCreateBean(beanName, mbdToUse, args); //这里的代码在前面已经讲的很清楚了 + if (logger.isTraceEnabled()) { + logger.trace("Finished creating instance of bean '" + beanName + "'"); + } + return beanInstance; + } + catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { + + throw ex; + } + catch (Throwable ex) { + throw new BeanCreationException( + mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); + } + } +``` + + + +doCreateBean那里就是一堆后置处理器的干预了,前面讲过 + + + +> 至此,创建Bean的流程就和前面讲的衔接上了。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +