mirror of
https://github.com/youthlql/JavaYouth.git
synced 2026-04-13 20:53:42 +00:00
1339 lines
33 KiB
Markdown
1339 lines
33 KiB
Markdown
---
|
||
title: Spring源码系列-第4章-Bean初始化流程
|
||
tags:
|
||
- Spring源码
|
||
categories:
|
||
- Spring
|
||
- 源码V1
|
||
keywords: Spring,框架,spring源码
|
||
description: 总结一下Bean的初始化
|
||
cover: 'https://npm.elemecdn.com/lql_static@latest/logo/spring.png'
|
||
abbrlink: 49f419ae
|
||
date: 2022-01-27 21:01:02
|
||
---
|
||
|
||
# 第4章-Bean初始化流程
|
||
|
||
## 流程图-bean初始化流程
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.7/spring-sourcecode-v1/flow_chart/bean%E5%88%9D%E5%A7%8B%E5%8C%96%E6%B5%81%E7%A8%8B.jpg">
|
||
|
||
## 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<String> 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<Boolean>) ((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<Object>) () -> {
|
||
smartSingleton.afterSingletonsInstantiated();
|
||
return null;
|
||
}, getAccessControlContext());
|
||
}
|
||
else {
|
||
smartSingleton.afterSingletonsInstantiated();
|
||
}
|
||
smartInitialize.end();
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
## 工厂Bean的初始化方式
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930171319531.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
### 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<Hello> {
|
||
|
||
@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调用栈
|
||
|
||
从这里开始看调用链
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930175345542.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930175539928.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
### DefaultListableBeanFactory#resolveBean()
|
||
|
||
```java
|
||
@Nullable
|
||
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
|
||
NamedBeanHolder<T> 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<T> parentProvider = parent.getBeanProvider(requiredType);
|
||
if (args != null) {
|
||
return parentProvider.getObject(args);
|
||
}
|
||
else {
|
||
return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
|
||
private <T> NamedBeanHolder<T> 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<String> 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
|
||
|
||
|
||
|
||
|
||
|
||
最后返回
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930180811270.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930181219048.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
## 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调用栈
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20211008174534713.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
### AbstractBeanFactory#doGetBean()
|
||
|
||
```java
|
||
protected <T> T doGetBean(
|
||
String name, @Nullable Class<T> 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<String> 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<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
|
||
|
||
// 正在创建的组件的名字池
|
||
/** Names of beans that are currently in creation. */
|
||
private final Set<String> 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的流程就和前面讲的衔接上了。
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|