Spring 源码学习 15:finishBeanFactoryInitialization(重点)
前言
可以说前面的都是准备工作,而接下来开始的才是重点,在这一步会完成 BeanFactory 的初始化,同时实例化单例 Bean。
具体怎么操作的,那就一起阅读源码吧!
不过在阅读源码之前,还是需要了解一些知识的。
什么是 FactoryBean ?
FactoryBean 是如何使用的 ?
Bean 是如何初始化的?
常说的循环依赖是怎么解决的?
什么是 FactoryBean ?
在官网的这篇文章《What's a FactoryBean?》中有相关解答,有兴趣的小伙伴可以看一下。
由内部使用的对象实现的接口,这些对象 BeanFactory 本身就是单个对象的工厂。如果 bean 实现此接口,则它将用作对象公开的工厂,而不是直接用作将自身公开的 bean 实例。
注意:实现此接口的 bean 不能用作普通 bean。 FactoryBean 以 bean 样式定义,但是为 bean 引用(getObject())公开的对象始终是它创建的对象。
FactoryBeans 可以支持单例和原型,并且可以按需延迟创建对象,也可以在启动时急于创建对象。
当生命一个 FactoryBean 时,会存在两个类型的 Bean,分别是 FactoryBean 本身,以及它需要创建的类型的 Bean。
下面是使用示例:
使用
1. PaidComponent
public class PaidComponent {
public PaidComponent() {
System.out.println("PaidComponent 无参构造被调用");
}
}
2. PaidComponentFactoryBean
@Component
public class PaidComponentFactoryBean implements FactoryBean<PaidComponent> {
@Override
public PaidComponent getObject() throws Exception {
System.out.println("PaidComponentFactoryBean 的 getObject 方法被调用");
return new PaidComponent();
}
@Override
public Class<?> getObjectType() {
return PaidComponent.class;
}
}
3 Test
public class AnnotationConfigApplicationTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(JavaConfig.class);
context.refresh();
System.out.println(context.getBean("paidComponentFactoryBean"));
System.out.println(context.getBean("&paidComponentFactoryBean"));
System.out.println(context.getBean(PaidComponent.class));
}
}
可以看出注册了两个 Bean, 一个是 paidComponentFactoryBean
,另一个是 &paidComponentFactoryBean
。
而直接获取 paidComponentFactoryBean
获取到的其实是 FactoryBean 的 getObject()
方法返回的类型。
finishBeanFactoryInitialization 源码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 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 bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 主要用于注释属性值的解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 尽早初始化 LoadTimeWeaverAware Bean,以便尽早注册其转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 停止使用临时的ClassLoader进行类型匹配。
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 设置 beanDefinition 元数据 不可以再修改
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化单例 bean
beanFactory.preInstantiateSingletons();
}
这里重点关注最后一行
beanFactory.preInstantiateSingletons();
preInstantiateSingletons
这块进入的是类 DefaultListableBeanFactory
类的源码。
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.
// 将 beanDefinitionNames 放到集合中
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 遍历
for (String beanName : beanNames) {
// 获取 bd 信息, 因为可能 定义了 parentBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象, 单例, 且不是懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否为 FactoryBean
if (isFactoryBean(beanName)) {
// FactoryBean 需要添加前缀 & ,通过 getBean(&beanName) 获取的是 FactoryBean 本身
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
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 {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 如果 Bean 实现了 SmartInitializingSingleton,
// 在这里会统一调用 afterSingletonsInstantiated 方法
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();
}
}
}
上面方法中通过循环 beanNames
进行初始化 Bean。
其中需要区别 BeanFactory 和 普通 Bean。 这也是我开始为什么先介绍了什么是 BeanFactory ?
下面就需要重点关注 getBean(beanName)
方法。
getBean
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
在 getBean
方法中调用的是 doGetBean
方法。
doGetBean
doGetBean 方法作用是:返回一个实例,该实例可以是指定bean的共享或独立的
。
该方法接受四个参数:
name – 要检索的 bean 的名称
requiredType – 要检索的 bean 的必需类型,这个可以为空
args –使用显式参数创建 bean 实例时要使用的参数(仅在创建新实例而不是检索现有实例时才应用)
typeCheckOnly –是否为类型检查而不是实际使用获取实例
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 去掉工厂引用的前缀, 同时转换别名
String beanName = transformedBeanName(name);
Object 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 + "'");
}
}
// 从缓存中如果获取到了, 普通 Bean 直接返回, FactoryBean 则返回 FactoryBean 创建的 Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 返回指定的 原型bean (prototype 类型的 Bean) 是否当前正在创建中(在当前线程内)。
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 检查 BeanFactory 是否存在这个 Bean 的 BeanDefinition
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 检查父容器中有没有定义
String nameToLookup = originalBeanName(name);
// 返回从父容器中查询的结果
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
// 将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。
// 标识本次调用方法,并非是要获取bean的类型,而是为了创建实例,将beanName存到alreadyCreated集合,代表该bean已经创建了,后面try。。catch有异常会清空该beanName
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
// 获取 Bean 的 BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 确保依赖的 Bean 已经被初始化, 比如 @DependsOn 注解
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
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);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
// 单例 bean
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.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 创建原型Bean
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 委托给实现类处理
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
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 ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
// Check if required type matches the type of the actual bean instance.
// 检查所需的类型是否与实际bean实例的类型匹配。
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;
}
上面代码比较长,基本上步骤已经添加相应的注释,基本上可以分为三步:
从缓存中获取到 Bean,创建对应的 Bean;
没有从缓存中获取到 Bean,创建对应的 Bean;
检查所需的类型是否与实际 bean 实例的类型匹配。
下面从这三个步骤分别介绍:
从缓存中获取到 Bean,创建对应的 Bean
**Object sharedInstance = getSingleton(beanName);
**
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
// private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 缓存了 单例 Bean
Object singletonObject = this.singletonObjects.get(beanName);
// 如果没有获取到, 并且当前 Bean 正在被创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 早期的单例对象, 先从 earlySingletonObjects 中获取
singletonObject = this.earlySingletonObjects.get(beanName);
// 没有从 earlySingletonObjects 缓存中获取到
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) {
// private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 从 singletonFactories 缓存中获取
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 添加到 earlySingletonObjects 缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 从 singletonFactories 缓存中删除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
这里可以看出,获取一个 Bean :
先从
singletonObjects
中获取 Bean;获取不到,从
earlySingletonObjects
中获取 Bean;获取不到,从
singletonFactories
中获取 Bean。
当然这一块涉及到循环引用,篇幅有限,后面会专门介绍循环引用。
没有从缓存中获取到 Bean,创建对应的 Bean
// Create bean instance.
if (mbd.isSingleton()) {
// 单例 bean
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.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 创建原型Bean
} else {
// 委托给实现类处理
String scopeName = mbd.getScope();
}
检查所需的类型是否与实际 bean 实例的类型匹配
总结
这里主要介绍了 Bean 的创建过程,主要是对整个过程有个大概的了解和熟悉,针对过程画图如下:
其中 Bean 的实例化主要关注单例 Bean 的实例化,后面准备对其进行详细研究后,再进行说明。
相关推荐
版权声明: 本文为 InfoQ 作者【程序员小航】的原创文章。
原文链接:【http://xie.infoq.cn/article/672f25dd0b6725d8c61cd1332】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
程序员小航
个人公众号:『 程序员小航 』 2020.07.30 加入
某不知名互联网公司 Java 程序员一枚。记录工作学习中的技术、开发及源码笔记;分享生活中的见闻感悟。
评论