相关文章
Spring IOC系列学习笔记一:前置刷新
Spring IOC系列学习笔记二:obtainFreshBeanFactory方法
Spring IOC系列学习笔记三:parseDefaultElement详解
Spring IOC系列学习笔记四:parseCustomElement解析
Spring IOC系列学习笔记五:context:component-scan 节点解析
Spring IOC系列学习笔记六:invokeBeanFactoryPostProcessors解析
Spring IOC系列学习笔记七:registerBeanPostProcessors
Spring IOC系列学习笔记八:finishBeanFactoryInitialization
Spring IOC系列学习笔记九:getBean方法
Spring IOC系列学习笔记十:createBean方法(上)
Spring IOC系列学习笔记十一:createBean方法(下)
Spring IOC系列学习笔记十二:@Autowire注解
文章目录
前言
该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。
代码块一:finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
1、初始化此上下文的转换服务
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
2、如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
3、初始化LoadTimeWeaverAware Bean实例对象
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.
4、冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
5、实例化所有剩余(非懒加载)单例对象
beanFactory.preInstantiateSingletons();
}
5、实例化所有剩余的(非懒加载)单例对象见代码块二
MergedBeanDefinition
直接翻译叫"合并的bean定义"。
对于一个bean来说可能存在一下几种情况。
-
该BeanDefinition存在父定义,首先使用父定义的参数来构建一个RootBeanDefinition,然后再用该BeanDefinition 来覆盖这个。
-
该BeanDefinition 不存在父定义,并且该BeanDefinition是一个RootBeanDefinition类型,则直接返回该RootBeanDefinition的克隆。
-
该BeanDefinition 不存在父定义,但是该BeanDefinition不是一个RootBeanDefinition类型,则该BeanDefinition创建一RootBeanDefinition类型。
之所以区分出2和3,是因为通常 BeanDefinition 在之前加载到 BeanFactory 中的时候,通常是被封装成 GenericBeanDefinition 或 ScannedGenericBeanDefinition,但是从这边之后 bean 的后续流程处理都是针对 RootBeanDefinition,因此在这边会统一将 BeanDefinition 转换成 RootBeanDefinition。
在我们日常使用的过程中,通常会是上面的第3种情况。如果我们使用 XML 配置来注册 bean,则该 bean 定义会被封装成:GenericBeanDefinition;如果我们使用注解的方式来注册 bean,也就是<context:component-scan /> + @Compoment,则该 bean 定义会被封装成 ScannedGenericBeanDefinition。
具体的代码再getMergedBeanDefinition方法中。截取一点代码如下:
if (mbd == null) {
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
对应2
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
对应3
mbd = new RootBeanDefinition(bd);
}
}
else {
对应了1
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
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);
}
代码块二:preInstantiateSingletons
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("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.
1、从缓存中获取所有的bean定义的名称
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
2、获取bean对应的MergedBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
3、不是抽象&&是单例&&不是懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
4、判断bean是否FactoryBean来类型
if (isFactoryBean(beanName)) {
5、通过getBean(&beanName)拿到的是FactoryBean本身;
通过getBean(beanName)拿到的是FactoryBean创建的Bean实例;
这儿是获取的get(&beanName)
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
5.1、是否需要提前初始化
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) {
5.2、提前初始化
getBean(beanName);
}
}
else {
6、不是FactoryBean类型直接获取bean实例
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
7、遍历所有的bean执行SmartInitializingSingleton接口的回调
for (String beanName : beanNames) {
7.1、获取bean实例
Object singletonInstance = getSingleton(beanName);
7.2、判断是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
7.3、执行afterSingletonsInstantiated方法
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
2、获取bean对应的MergedBeanDefinition见代码块三
4、判断bean是否FactoryBean来类型见代码块六
5、getBean方法我们后续再单独讲解。
代码块三:getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
1、从缓存中获取,如果获取到则直接返回
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
2、从缓存中获取bean实例
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
if (bd.getParentName() == null) {
3.1、没有父定义,就不需要与父定义进行合并
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
3.2、该bean是RootBeanDefinition类型,则直接对该bean克隆一个RootBeanDefinition
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
3.3、对该bean创建一个RootBeanDefinition
mbd = new RootBeanDefinition(bd);
}
}
else {
4.1、有父定义,先创建父定义需要与父定义合并。
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
4.2、获取父定义的bean名字
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
4.3、如果beanName与父定义的bean不同,获取父亲的合并bean,因为父亲可能也有父亲就是该bean的爷爷需要先进行合并
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
4.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
4.5、如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
反之抛出异常
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.
4.6、创建父bean的RootBeanDefinition
mbd = new RootBeanDefinition(pbd);
4.7、子覆盖父定义
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
5.1、如果没有scope属性则设置成singleton
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()) {
5.2、containingBd(顶级的bean)不为空&&containingBd不是单例&&mbd是单例,则将mbd设置成containingBd的scope
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()) {
6、放入合并bean的缓存中
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
4.2、获取父定义的bean名字见代码块四
4.3、如果beanName与父定义的bean不同,获取父亲的合并bean,因为父亲可能也有父亲就是该bean的爷爷需要先进行合并见代码块五
4.6 和 4.7 就是合并操作,也就是我们之前一直说的 MergedBeanDefinition 的由来。
6、将该 beanName 与 MergedBeanDefinition 放到 mergedBeanDefinitions 缓存,后续再走到代码块2时,就会直接返回缓存里的数据。
代码块四:transformedBeanName
protected String transformedBeanName(String name) {
1、transformedBeanName删除&为开头的beanName
2、canonicalName确定原始bean名称,将本地定义的别名解析为规范名称
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
String beanName = name;
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
return beanName;
}
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
FactoryBean
在这儿引入有FactoryBean的概念,Spring中一般是通过反射机制利用bean的class属性来进行实例化,而FactoryBean是执行getObject()方法自己去创建bean的实例,所以如果是FactoryBean则只需要实现他的getObject()方法获取实例。
public class AppleFactoryBean implements FactoryBean<Apple> {
@Override
public Apple getObject() throws Exception {
Apple apple = new Apple();
apple.setName("bigApple");
return apple;
}
@Override
public Class<?> getObjectType() {
return Apple.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
为了区分FactoryBean和FactoryBean实例,spring对beanName使用&来进行区分,带有&的就是获取FactoryBean本身,不带有&就是获取FactoryBean执行了getObject方法创建的bean实例。
代码块五:getMergedBeanDefinition
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
1、解析别名
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
2、beanDefinitionMap不包含beanName&&父bean实现ConfigurableBeanFactory
则获取父BeanFactory去获取beanName的MergedBeanDefinition
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
3、在当前BeanFactory中解析beanName的MergedBeanDefinition
return getMergedLocalBeanDefinition(beanName);
}
父 BeanFactory
在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。最常见的例子就是:Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。
我们回到代码块二继续执行介绍4进入代码块六
代码块六:isFactoryBean
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
1、解析别名
String beanName = transformedBeanName(name);
2、获取bean的实例对象
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found -> check bean definition.
3、缓存中不存在beanName&&父BeanFactory实现了ConfigurableBeanFactory
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
3.1、判断父beanFactory是不是FactoryBean
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
4、通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
2、获取bean的实例对象见代码块七
4、通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean见代码块八
代码块七:getSingleton
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
1、从单例缓存中获取beanName实例
Object singletonObject = this.singletonObjects.get(beanName);
2、singletonObject为空&&单例的bean正在被创建
if (singletonObject为空&& == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
3、从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
singletonObject = this.earlySingletonObjects.get(beanName);
4、singletonObject为null&&允许早期曝光
if (singletonObject == null && allowEarlyReference) {
5、从单例工厂中获取beanName的ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
6、单例工厂执行getObject获取bean的实例
singletonObject = singletonFactory.getObject();
7、放入到早期曝光的缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
8、已经实例化,从单例工厂中移除
this.singletonFactories.remove(beanName);
}
}
}
}
9、返回实例
return singletonObject;
}
这个方法非常重要是解决循环依赖的核心代码。
解决循环引用逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,所以最终我们看到的还是完整 bean 实例。
另外这个代码块中引进了4个重要缓存:
- singletonObjects:beanName->单例bean实例
- earlySingletonObjects:beanName->单例bean实例,早期曝光的单例bean,还未进行属性填充初始化。
- singletonFactories:beanName->ObjectFactory
- singletonsCurrentlyInCreation :正在创建单例beanName的beanName集合。
singletonObjects 、earlySingletonObjects、singletonFactories构成了一个三级缓存的概念
代码块八:isFactoryBean
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
// 1.拿到beanName对应的Bean实例的类型
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// 2.返回beanType是否为FactoryBean本身、子类或子接口
return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
}
1.拿到beanName对应的Bean实例的类型见代码块九,这儿执行的是AbstractAutowireCapableBeanFactory的predictBeanType方法。
代码块九:predictBeanType
@Override
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
// 1.拿到beanName的类型
Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
// Apply SmartInstantiationAwareBeanPostProcessors to predict the
// eventual type after a before-instantiation shortcut.
// 2.应用SmartInstantiationAwareBeanPostProcessors后置处理器,来预测实例化的最终类型,
// SmartInstantiationAwareBeanPostProcessors继承了InstantiationAwareBeanPostProcessor,
// InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法可以改变Bean实例的类型,
// 而SmartInstantiationAwareBeanPostProcessors的predictBeanType方法可以预测这个类型
if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 3.调用predictBeanType方法
Class<?> predicted = ibp.predictBeanType(targetType, beanName);
if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
FactoryBean.class.isAssignableFrom(predicted))) {
// 4.如果predicted不为空 && (typesToMatch长度不为1 || typesToMatch[0]不为FactoryBean.class ||
// predicted是FactoryBean本身、子类或子接口),则返回predicted
return predicted;
}
}
}
}
// 5.否则返回beanName的类型
return targetType;
}
总结
本文主要执行了创建bean之前的一些准备操作,引入FactoryBean这一个特殊的bean,获取BeanDefinition的MergedBeanDefinition,转换成RootBeanDefinition。
引入一下几个缓存:
- mergedBeanDefinitions:beanName->合并的bean定义。
- singletonObjects:beanName->单例bean实例
- earlySingletonObjects:beanName->单例bean实例,早期曝光的单例bean,还未进行属性填充初始化。
- singletonFactories:beanName->ObjectFactory
- singletonsCurrentlyInCreation :正在创建单例beanName的beanName集合。