前言:经过前几篇文章的讲解,我们已经得到了BeanDefinition,接下来将分析Bean的加载。


获取Bean的入口:AbstractApplicationContext#getBean

     public Object getBean(String name) throws BeansException {
// 检测bean工厂是否存活
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}

分析:
首先检查BeanFactory是否存活,还记得之前分析过的prepareRefresh()方法吗?如果不记得了,请翻看之前的文章,那里设置了active的值,然后在这里做检查。如果BeanFactory关闭,则抛出异常。

     protected void assertBeanFactoryActive() {
if (!this.active.get()) {
if (this.closed.get()) {
throw new IllegalStateException(getDisplayName() + " has been closed already");
} else {
throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
}
}
}

AbstractBeanFactory#getBean

 @Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

最终切入点:

 // AbstractBeanFactory
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 返回bean名称,剥离工厂引用前缀
// 如果name是alias,则获取对应映射的beanName
final String beanName = transformedBeanName(name);
Object bean; // 从缓存或实例工厂中获取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 + "'");
}
}
// 完成FactoryBean的相关处理,并用来获取FactoryBean的处理结果
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// Spring只能解决单例模式下的循环依赖,在原型模式下如果存在循环依赖则抛出异常
// 这里检测原型模式下,该bean是否在加载,如果在加载则抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
} // 如果当前容器中没有找到,则从父类容器中加载
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
/**
* 调用{@link DefaultListableBeanFactory#containsBeanDefinition(String)}方法
* 其实就是在beanDefinitionMap中判断是否存在beanName对应的BeanDefinition
*/
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 确定原始的beanName
String nameToLookup = originalBeanName(name);
// 如果父类容器为AbstractBeanFactory,则委托父类处理
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) { // 用明确的args从parentBeanFactory中,获取Bean对象
// Delegation to parent with explicit args.
// 委托给父类构造函数getBean()处理
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) { // 用明确的requiredType从parentBeanFactory中,获取Bean对象
// No args -> delegate to standard getBean method.
// 没有args,委托给标准的getBean()处理
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
// 直接使用nameToLookup从parentBeanFactory中获取Bean对象
return (T) parentBeanFactory.getBean(nameToLookup);
}
} // 如果不仅仅是做类型检查,而是创建bean,这里需要记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
} try {
/**
* 从容器中获取beanName对应的GenericBeanDefinition对象,并转换成RootBeanDefinition对象
* GenericBeanDefinition的创建{@link BeanDefinitionReaderUtils#createBeanDefinition}方法
*/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查合并的BeanDefinition
checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on.
// 处理所依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 若给定的依赖bean已经注册为依赖给定的bean
// 即循环依赖情况,抛出BeanCreationException异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 缓存依赖调用
registerDependentBean(dep, beanName);
try {
// 递归处理依赖 Bean
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// bean实例化
// Create bean instance.
// 单例模式
/**
* 这里有个已创建bean的重要方法createBean
* {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])}
*/
if (mbd.isSingleton()) {
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.
// 显式从单例缓存中删除Bean实例
// 因为单例模式下为了解决循环依赖,可能它已经存在,所以销毁它
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) { // 原型模式
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 前置处理
beforePrototypeCreation(beanName);
/**
* 创建bean {@link AbstractAutowireCapableBeanFactory#createBean}
*/
prototypeInstance = createBean(beanName, mbd, args);
} finally {
/**
* 后置处理 与前置处理相反从{@link prototypesCurrentlyInCreation}中移除
*/
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else { //其他作用域
// 获得scopeName对应的Scope对象
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
/**
* 从指定的scope下创建bean
* {@link SimpleThreadScope#get方法}
*/
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;
}
} // 检查需要的类型是否符合bean的实际类型
// 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;
}

分析:

这里的代码稍微有点多,但是这段代码非常重要,我们一步步来进行分析。

AbstractBeanFactory#transformedBeanName

 public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
// 循环,从aliasMap中获取最终的beanName
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
} // BeanFactoryUtils
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null"); // 如果beanName不是以"&"开始,则直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// computeIfAbsent方法,分两种情况:
// #1.不存在,则执行后面的lambda表达式,beanName的值就是name的值,并将结果添加到缓存。
// #2.存在,则直接返回name的值。
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}

分析:

transformedBeanName函数的功能:返回beanName,剥离工厂引用前缀。

在BeanFactoryUtils#transformedBeanName中:

  • 如果beanName不是以"&"开始,则直接返回。
  • 如果transformedBeanNameCache缓存中存在已经解析好的beanName,则直接返回。
  • 不存在,则剥离"&"符号后,将beanName加入缓存,然后再返回beanName。
  • SimpleAliasRegistry#canonicalName中循环从aliasMap中获取最终的beanName。

DefaultSingletonBeanRegistry#getSingleton

 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从单例缓存中加载Bean
Object singletonObject = this.singletonObjects.get(beanName);
// 缓存中bean为空,且当前bean正在创建
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 做同步
synchronized (this.singletonObjects) {
// 从earlySingletonObjects集合中获取
singletonObject = this.earlySingletonObjects.get(beanName);
// earlySingletonObjects集合中没有,其允许提前创建
if (singletonObject == null && allowEarlyReference) {
// 从singletonFactories中获取对应的ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 获取bean
singletonObject = singletonFactory.getObject();
// 将bean添加到earlySingletonObjects集合中
this.earlySingletonObjects.put(beanName, singletonObject);
// 从singletonFactories中移除对应的
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}

分析:

在加载bean时,首先从单例缓存中获取bean对象。

  • 首先从单例缓存中获取bean对象,如果缓存中存在bean对象则直接返回(单例模式的bean在创建过程中会进行缓存[singletonObjects])。
  • 如果缓存中bean对象为空,且当前bean正在创建,则从earlySingletonObjects中获取。
  • 如果earlySingletonObjects集合中不存在,且允许提前创建bean,则从singletonFactories中获取单例工厂,若singleFactory不为空,则通过getObject方法获取bean,并将bean对象加入到earlySingletonObjects集合中,然后从singleFactory集合中移除对应的单例工厂对象。

注意这里涉及到三个集合:

  • singletonObjects (一级)单例对象 Cache
  • earlySingletonObjects (二级)提前曝光的单例对象 Cache
  • singletonFactories (三级)单例对象工厂 Cache
 /**
* Cache of singleton objects: bean name to bean instance.
* 存放的是单例 bean 的映射。
* <p>
* 对应关系为 bean name --> bean instance
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /**
* Cache of singleton factories: bean name to ObjectFactory.<br/>
* 存放的是 ObjectFactory,可以理解为创建单例 bean 的 factory 。
* <p>
* 对应关系是 bean name --> ObjectFactory
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /**
* Cache of early singleton objects: bean name to bean instance.<br/>
* 存放的是早期的 bean,对应关系也是 bean name --> bean instance。
* <p>
* 它与 {@link #singletonFactories} 区别在于 earlySingletonObjects 中存放的 bean 不一定是完整。
* <p>
* 从 {@link #getSingleton(String)} 方法中,我们可以了解,bean 在创建过程中就已经加入到 earlySingletonObjects 中了。
* 所以当在 bean 的创建过程中,就可以通过 getBean() 方法获取。
* <p>
* 这个 Map 也是【循环依赖】的关键所在。
*/
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

这三个缓存集合就是解决Spring中循环依赖的所在,具体流程:

  • 首先从一级缓存singletonObjects中获取,如果为null,且当前bean正在被创建,则从二级缓存earlySingletonObjects中获取,如果还是为null,且允许singletonFactories通过getObject获取,则从三级缓存singletonFactories中获取,如果得到,则将其加入二级缓存earlySingletonObjects中,并从三级缓存singletonFactories中移除对应的工厂对象(因为单例模式的bean只会被创建一次),这样三级缓存就升级到二级缓存了,所以二级缓存存在的意义就是缓存三级缓存中ObjectFactory#getObject的执行结果,提前曝光单例Bean对象。

如果从单例缓存中得到bean对象,则会调用getObjectForBeanInstance方法进一步处理,因为从缓存中得到的bean是最原始的bean,并不一定是最终所需要的bean对象。

AbstractAutowireCapableBeanFactory#getObjectForBeanInstance

     protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { String currentlyCreatedBean = this.currentlyCreatedBean.get();
if (currentlyCreatedBean != null) {
registerDependentBean(beanName, currentlyCreatedBean);
} return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}

分析:

  • 首先如果bean正在被创建,则会注册依赖关系(registerDependentBean,该函数还未仔细分析,后续查漏补缺)。
  • 然后调用父类的getObjectForBeanInstance方法获取Bean对象。

AbstractBeanFactory#getObjectForBeanInstance

 protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 如果name是工厂类的引用名称(name以"&"开头)
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
// 如果是NullBean则直接返回
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果beanInstance不是FactoryBean则抛出异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
} // 走到这里,说明我们现在已经有一个Bean实例,当然该实例可能会是一个正常的Bean或者又是一个FactoryBean
// 如果是FactoryBean,则创建Bean
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 如果beanInstance不是Factory或者beanName以&开头,则直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
} Object object = null;
// 若BeanDefinition为null,则从缓存中加载bean对象
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
// 如果Object仍然为空,则可以确认beanInstance一定是FactoryBean。从而使用FactoryBean获取Bean对象
// 通过beanInstance instanceof FactoryBean这里判断,如果beanInstance不是FactoryBean已经直接返回了
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 检测beanDefinitionMap中,也就是所有已加载的类中是否定义了beanName
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
// 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
// 如果指定beanName是子Bean的话同时会合并父类的相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义的,而不是程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 核心函数,使用FactoryBean获得Bean对象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

分析:

  • 如果beanName以"&"开头,表示是工厂类的实例对象,如果beanInstance为NullBean则直接返回,如果beanInstance不为FactoryBean,则抛出异常,这里主要是校验beanInstance的正确性
  • 如果beanInstance不是FactoryBean或者beanName不以"&"开头,则直接返回beanInstance对象。这里主要是对非FactoryBean的处理
  • 如果BeanDefinition为null,则从缓存中加载bean对象,如果还是为null,则可以确定beanInstance一定是FactoryBean,具体看前面的两个判断
  • 检测beanDefinitionMap中是否已经加载了该bean,如果加载过着会判断是否需要合并父类的相关属性--getMergedLocalBeanDefinition方法。
  • 最后使用getObjectFromFactoryBean获取bean对象。

AbstractBeanFactory#getMergedLocalBeanDefinition

 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 快速从缓存中获取,如果不为null,则直接返回
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// 获取RootBeanDefinition,如果返回的BeanDefinition是子类的bean的话,则合并父类相关属性
// getBeanDefinition函数从beanDefinitionMap中取出对应的BeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

分析:

  • 首先检查缓存中是否存在已经转换过的RootBeanDefinition对象,如果存在,则直接返回。
  • 通过getMergedBeanDefinition函数进行BeanDefinition的转换。

AbstractBeanFactory#getMergedBeanDefinition

 protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
// 做同步
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// 如果containingBd为null,则从mergedBeanDefinitions中尝试获取
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 如果集合中不存在RootBeanDefinition
if (mbd == null) {
// 并且无父类
if (bd.getParentName() == null) {
// 如果BeanDefinition是RootBeanDefinition类型,则直接拷贝
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
// 否则新创建一个RootBeanDefinition对象
mbd = new RootBeanDefinition(bd);
}
} else {
// 如果存在父类
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
// 首先获取父类的beanName
String parentBeanName = transformedBeanName(bd.getParentName());
// beanName与父类beanName不相等
if (!beanName.equals(parentBeanName)) {
// 通过父类beanName返回BeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
} else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
} else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
} // Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
} // A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
} // Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
} return mbd;
}
}

分析(注意给方法是同步的,Spring中很多这种同步方法):

  • 首先从缓存中查找是否存在RootBeanDefinition,如果不存在,且当前BeanDefinition无父类,则会得到一个RootBeanDefinition对象(若BeanDefinition本身就是RootBeanDefinition,则直接拷贝,否则就实例化一个对象)。
  • 如果BeanDefinition存在父类,且父类名beanName与子类beanName不相等,则通过父类去创建BeanDefinition对象(getMergedBeanDefinition),如果beanName不相等,则通过父类工厂去创建BeanDefinition对象。
  • RootBeanDefinition对象创建好后,会设置对象的作用域,如果之前为设置,则默认为单例模式(后续的作用域设置理解得不是很清楚),最后会缓存新生成的RootBeanDefinition对象。

FactoryBeanRegistrySupport#getObjectFromFactoryBean

 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 为单例模式,其缓存中存在该bean实例
if (factory.isSingleton() && containsSingleton(beanName)) {
/**
* 做同步,内部其实使用的就是{@link DefaultSingletonBeanRegistry#singletonObjects}
*/
synchronized (getSingletonMutex()) {
// 从缓存中获取指定的factoryBean
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 为空,则从FactoryBean中获取对象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
// 再次从缓存中获取bean对象,主要是因为循环依赖
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
} else {
// 需要后续处理
if (shouldPostProcess) {
// 如果该Bean处于创建中,则返回非处理对象,而不是存储该对象
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// 单例bean的前置处理 用于添加标志,当前bean正处于创建中
beforeSingletonCreation(beanName);
try {
// 对FactoryBean获取的对象进行后置处理,返回生成的对象
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
} finally {
// 单例bean的后置处理 和前置处理相反,前置添加,后置移除 移除标志,当前bean不处于创建中
afterSingletonCreation(beanName);
}
}
// 添加到factoryBeanObjectCache中进行缓存
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
} else {
// 不满足第一个条件,不是单例,或者缓存中不存在,则从FactoryBean中获取对象
Object object = doGetObjectFromFactoryBean(factory, beanName);
// 需要后续处理
if (shouldPostProcess) {
try {
// 对FactoryBean获取的对象进行后处理
// 返回生成的对象
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}

由于篇幅原因该函数将在后续文章中继续分析,文章太长笔者认为不宜阅读。

总结

本文才进入加载bean的流程,从单例缓存中获取单例bean对象,后续继续强行开撸。


by Shawn Chen,2019.04.20,上午。

【spring源码分析】IOC容器初始化(六)的更多相关文章

  1. SPRING源码分析:IOC容器

    在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...

  2. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  3. spring源码分析---IOC(1)

    我们都知道spring有2个最重要的概念,IOC(控制反转)和AOP(依赖注入).今天我就分享一下spring源码的IOC. IOC的定义:直观的来说,就是由spring来负责控制对象的生命周期和对象 ...

  4. spring 源码之 ioc 容器的初始化和注入简图

    IoC最核心就是两个过程:IoC容器初始化和IoC依赖注入,下面通过简单的图示来表述其中的关键过程:

  5. Spring源码阅读-IoC容器解析

    目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...

  6. Spring 源码剖析IOC容器(一)概览

    目录 一.容器概述 二.核心类源码解读 三.模拟容器获取Bean ======================= 一.容器概述 spring IOC控制反转,又称为DI依赖注入:大体是先初始化bean ...

  7. Spring源码解析-IOC容器的实现

    1.IOC容器是什么? IOC(Inversion of Control)控制反转:本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,即交给了IOC容器,Spring的IO ...

  8. Spring源码解析-IOC容器的实现-ApplicationContext

    上面我们已经知道了IOC的建立的基本步骤了,我们就可以用编码的方式和IOC容器进行建立过程了.其实Spring已经为我们提供了很多实现,想必上面的简单扩展,如XMLBeanFacroty等.我们一般是 ...

  9. Spring源码之IOC容器创建、BeanDefinition加载和注册和IOC容器依赖注入

    总结 在SpringApplication#createApplicationContext()执行时创建IOC容器,默认DefaultListableBeanFactory 在AbstractApp ...

  10. 【spring源码分析】IOC容器初始化(总结)

    前言:在经过前面十二篇文章的分析,对bean的加载流程大致梳理清楚了.因为内容过多,因此需要进行一个小总结. 经过前面十二篇文章的漫长分析,终于将xml配置文件中的bean,转换成我们实际所需要的真正 ...

随机推荐

  1. 不一样的 SQL Server 日期格式化

    不一样的 SQL Server 日期格式化 Intro 最近统计一些数据,需要按天/按小时/按分钟来统计,涉及到一些日期的格式化,网上看了一些文章大部分都是使用 CONVERT 来转换的,SQL Se ...

  2. Core文件简单介绍及生成设置方法

    Core文件简单介绍及生成设置方法 Core文件其实就是内存的映像,当程序崩溃时,存储内存的相应信息,主用用于对程序进行调试.当程序崩溃时便会产生core文件,其实准确的应该说是core dump 文 ...

  3. OKR能解决996吗?德鲁克怎么看?

    最近网络上热议的“996”,不由让人想起我们的邻国日本.他们在20年前就有过一个热词“过劳死”,就是职场加班太严重导致的猝死. 最近有一本书新书<过劳时代>,说的就是日本20年前的过劳死. ...

  4. Fork/Join框架详解

    Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.Fork/Join框架要完成两件事情: 1.任务分 ...

  5. Windows10系统:任务栏中电池图标消失问题的解决方法

    一.问题: 电池图标对我们来说,基本是没有什么操作对它进行的,但这并不代表它不重要. 持续充电的时候自然觉得没什么,但一旦电脑脱离充电状态,我们还是会经常性地把鼠标放在电池图标上.只有清楚地了解电脑的 ...

  6. Python学习之路——Day01

    Day01 一.编程和编程语言 编程语言是人与计算机之间交流沟通的介质 编程就是人实现通过让计算机实现动作的文件 二.计算机的组成 1.控制器:负责控制指挥计算机硬件运行 2.运算器:负责数学与逻辑运 ...

  7. 【Android Studio安装部署系列】三十二、Android模拟器Genymotion安装使用教程详解

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 一.注册\登录 打开Genymotion官网,https://www.genymotion.com/ ,首先点击右上角的Sign in进行 ...

  8. 【Android Studio安装部署系列】三十六、Android studio3.2使用过程中注意事项

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio升级到3.2之后,运行旧项目的时候出现了各种情况,特此记录下. 一.打包选项多了,一般情况下选择APK即 ...

  9. ToastCustomUtil【简单的Toast封装类】【自定义Toast的显示风格】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 ToastUtil + ToastCustom结合.主要解决低版本机型上系统toast显示不好看的问题. 效果图 代码分析 在Toa ...

  10. 使用 ASP.NET Core MVC 创建 Web API(三)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 十 ...