前言:经过前几篇文章的讲解,我们已经得到了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作业报错特殊案例

    一个作业报错,报错信息如下,从错误信息根本看不出为什么出错,手工运行作业又成功了.一时不清楚什么原因导致作业出错. Message Executed as user: NT SERVICE\SQLSE ...

  2. 理解Device Tree Usage(续)

    4 How Interrupts work   与遵循树的自然结构的地址范围转换不同, 中断信号可以起源于或者终止于板卡上的任何设备. 与设备树中自然表示的设备寻址不同,中断信号的表示独立于设备树节点 ...

  3. ReactiveSwift源码解析(三) Signal代码的基本实现

    上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...

  4. Linux 桌面玩家指南:18. 使用 Docker 隔离自己的开发环境和部署环境

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  5. Java使用Try with resources自动关闭资源

    Try-with-resources Try-with-resources是Java7中一个新的异常处理机制,它能够很容易地关闭在try-catch语句块中使用的资源. 利用Try-Catch-Fin ...

  6. Go语言JSON数据相互转换

    目录 结构体转json map转json int转json slice转json json反序列化为结构体 json反序列化为map 结构体转json 结构体转json示例: package main ...

  7. Java数据结构和算法 - 数组

    Q: 数组的创建? A: Java中有两种数据类型,基本类型和对象类型,在许多编程语言中(甚至面向对象语言C++),数组也是基本类型.但在Java中把数组当做对象来看.因此在创建数组时,必须使用new ...

  8. Python后台开发Django(数据库)

    如果使用pymysql,则可以在view中直接import pymysql进行操作,与原操作无区别 Django数据库框架支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在s ...

  9. GoLand2019 激活码

    此教程对最新2019版本GoLand有效!!! 本教程对windows.mac.ubuntu全系统可用 此教程实时更新,请放心使用:如果有新版本出现猪哥都会第一时间尝试激活: goland官网下载地址 ...

  10. 【Android Studio安装部署系列】三、Android Studio项目目录结构

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 简单介绍下Android studio新建项目的目录结构. 常用项目结构类型 在Android Studio中,提供了以下几种项目结 ...