在上一章中我有提到过,无论 Spring 采用的是哪种方式去实现 IoC (无论是注解、xml、或者是其他任何一种方式),在真正调用 getBean() 之前容器中都不存在任何一个 Bean 实例。
或许你有疑问,ApplicationContext 这个容器在初始化的同时内部不是已经缓存 Bean 实例了么?那是因为在 refresh() 方法中就已经调用过 getBean() 了,Bean 的初始化流程已经被执行过了。
因此,Bean 实例化的核心就在于 getBean() 这个方法内部的逻辑。下面就具体看看它内部都干了什么工作。
深入 AbstractBeanFactory.getBean(String name, Class<T> requiredType)
可以发现,这里调用的是 AbstractBeanFactory.getBean(),它是 DefaultListableBeanFactory 的父类。
AbstractBeanFactory 对 getBean() 进行了不同的重载,用于不同参数的 doGetBean() 调用。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
继续深入 AbstractBeanFactory.doGetBean(String name, Class<T> requiredType)
这个方法的代码非常的多,但我们可以先明确它的核心逻辑 —— 尝试先从缓存中获取 Bean 实例,如果获取失败则创建 Bean 实例。
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// 尝试从缓存中获取bean实例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 省略日志打印...
// 获取到bean实例有可能是一个工厂Bean
// 如果获取到的beanInstance是工厂bean, 那么就会进行相应的处理获取到bean实例返回
// 若不是工厂bean, 直接返回bean实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else { // 缓存池中获取到的 beanInstance 为空, 那么就需要执行实例化的逻辑了
// 需要获取的prototype类型的Bean正在处于创建中
// 或许正在解决循环依赖的问题
// 这里就会抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取到父工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
// 检查parent工厂中是否已经解析并注册了相关的beanDefinition
// 如果parent工厂中的BeanDefinitionMap中包含了相关的beanName
// 那么调用parent工厂的getBean()进行初始化
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对应的BeanDefinition已经处于创建中了
// 底层就是放入一个Set容器 —— alreadyCreated中
markBeanAsCreated(beanName);
}
try {
// 获取到合并的BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查这个BeanDefinition 是否是一个抽象类型的
// 抽象类不能被实例化
checkMergedBeanDefinition(mbd, beanName, args);
// 处理 depends-on, 如果存在的话
// depends-on 指定了某个bean在初始化前需要提前实例化好的一些bean
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 + "'");
}
// 注册依赖的Bean
registerDependentBean(dep, beanName);
try {
// 实例化依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 创建单例 bean
// 使用了lamda进行createBean()的回调
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 内部就是真正实例化bean的逻辑
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// ...
}
});
// 获取到的sharedInstance可能是工厂Bean
// 进行相应处理获取到 beanInstance
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);
// 实例化多例bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 后置处理
afterPrototypeCreation(beanName);
}
// 获取到的sharedInstance可能是工厂Bean
// 进行相应处理获取到 beanInstance
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 其他scope的bean实例化
// 其实原理都差不多
else {
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 {
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) {
// ...
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 如果调用的 getBean() 参数中指定了 requireType
// 就会在这里进行一个强制类型转换
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) {
// ...
}
}
return (T) bean;
}
上述方法中我们需要关注几个核心逻辑,分别是 "从单例缓存池中获取Bean实例"、"实例化单例Bean"、"对工厂Bean进行处理",其中 "对工厂Bean进行处理" 这部分的逻辑会涉及到 AOP 相关的内容,因此本篇主要分析前两者。
一、从单例缓存池中获取 bean 实例
深入 AbstractBeanFactory.getSingleton(String beanName)
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
继续深入 DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)
下面这个方法会尝试从三个缓存中获取 beanInstance,关于三级缓存的内容我在前一篇有过简单的介绍,它主要是用于解决循环依赖问题的。
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 通过一级缓存获取bean实例
Object singletonObject = this.singletonObjects.get(beanName);
// 如果发现缓存中不存在对应的bean实例, 并且发现这个bean正处于创建过程中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 那么就会进行一个同步
// 避免并发环境下出现的读写不一致的问题
synchronized (this.singletonObjects) {
// 尝试从第二层缓存获取实例
singletonObject = this.earlySingletonObjects.get(beanName);
// 若第二层缓存也没获取到, 并且允许通过实例工厂获取实例
if (singletonObject == null && allowEarlyReference) {
// 尝试从第三层缓存获取单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 通过工厂获取到实例
singletonObject = singletonFactory.getObject();
// 放入第二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 第三层缓存中移除相应的工厂实例
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
对于 isSingletonCurrentlyInCreation 这个参数我有必要单独说明一下,它会判断对应的单例对象是否在创建中,当单例对象没有被完全创建时,比如A类依赖于B类,那么就需要先创建B类的实例,此时实例A就处于一个创建中的状态。
这里我们先留个眼熟,大概知道 Spring 在通过单例缓存池获取实例时,会经过三级缓存尝试获取,如果都获取不到,才会对 bean 实例进行创建。
二、实例化 Bean
深入到 DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)
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) {
// ...
}
if (logger.isDebugEnabled()) {
// ...
}
// 初始化实例前的前置处理
beforeSingletonCreation(beanName);
// 如果成功创建了,这个标识就会被置为true
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 这里就会执行 lamda 中的 createBean() 方法了
// 紧接着调用 createBean() 方法返回的单例工厂来获取到实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (Exception ex) {
// ...
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 后置处理
afterSingletonCreation(beanName);
}
// 当 newSingleton 标识为 true, 就意味着bean实例已经成功创建了
if (newSingleton) {
// 将创建的bean实例添加到缓存中
addSingleton(beanName, singletonObject);
}
}
// 最后把这个单例bean实例给返回
return singletonObject;
}
}
这个方法会涉及到两个核心的逻辑:
- 回调 lambda 中的逻辑,执行 createBean() 方法获取到返回的单例工厂实例,紧接着调用这个工厂实例获取到 Bean 实例。
- 将创建好的 Bean 实例放入单例缓存池。
2.1 执行 createBean() 创建 Bean 实例
深入 doGetBean() 方法内部的 lambda 表达式中的 AbstractAutowireCapableBeanFactory.createBean(tring beanName, RootBeanDefinition mbd, @Nullable Object[] args)
@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;
// 通过解析 beanDefinition 中的全限定类名获取到 Class 对象
// 底层通过反射来实现的
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 将Class对象set到RootBeanDefinition上
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
// ...
}
try {
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 {
// 通过设置上了 Class 对象的 BeanDefinition 来创建 Bean 实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
// 返回实例
return beanInstance;
}
catch (Exception e) {
// 省略....
}
}
继续深入 AbstractAutowireCapableBeanFactory.doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
// Bean的包装器, 对bean的一层封装, 增加了一些额外的描述信息
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果从factoryBeanInstanceCache中获取到的instanceWrapper为空
// 那么就需要进行bean实例的创建
// 创建bean实例, 这里会将创建出的bean实例用BeanWrapper进行包装
if (instanceWrapper == null) {
// 当这个方法执行完成之后, 我们会获取到一个属性都为空的Bean实例包装
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 返回BeanWrapper封装的bean实例
final Object bean = instanceWrapper.getWrappedInstance();
// 获取到Bean的Class对象
Class<?> beanType = instanceWrapper.getWrappedClass();
// 如果类型不是一个NullBean, 那么在RootBeanDefinition中设置上相应的Type属性
if (beanType != NullBean.class) {
// 这里设置的是 "已经被解析的Bean的类型"
mbd.resolvedTargetType = beanType;
}
// 这里就是一个后置的处理, 可以忽略
synchronized (mbd.postProcessingLock) {
// ...
}
// 尽早地缓存这个bean实例, 以解决循环引用的问题
// 判断是否是单例(只有单例才会被缓存)、是否允许循环引用、当前bean是否处于一个created状态
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
// ...
}
// 这里就会对单例缓存池进行一个处理, 内部就是解决循环依赖的核心逻辑
// 需要注意的是, 到这一步, 并没有将实例放入第一层缓存(singletonObjects)中
// 内部的逻辑是:
// 若 singletonObjects 不包含对应的bean
// 那么就在三级缓存 singletonFactories 放入对应的 singletonFactory 实例
// 并且在二级缓存 earlySingletonObjects 中移除 key=beanName 的键值对
// 然后 registeredSingletons 中添加相应的 beanName, 表示相应的单例已经被注册了
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 获取被初始化的Bean实例
Object exposedObject = bean;
try {
// 这个方法中, 就封装了注入属性的一个逻辑
populateBean(beanName, mbd, instanceWrapper);
// 初始化给定的bean实例
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
// 省略异常逻辑
}
if (earlySingletonExposure) {
//... 省略这部分的逻辑
}
// 注册bean销毁时的一些逻辑
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
// ...
}
return exposedObject;
}
上述方法存在两个核心逻辑:
- 实例化 Bean
- 为 Bean 注入属性
由于篇幅太长,Bean 的属性注入在下一篇文章中进行分析。这里我们先看 Bean 的实例化流程。
继续深入 AbstractAutowireCapableBeanFactory.createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
// 通过不同的创建策略(比如工厂方法、构造器注入、简单实例化)来创建出指定的bean实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 确保 Class 能够成功获取到
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 若 Class 不为空, 且访问修饰符是非public, 且非public不允许访问
// 这里就会抛出一个异常
// 其实第二个条件 Spring 都能通过反射机制提供的setAccessible(true)来解决
// 主要是第三个条件为true时, 就无法实例化了
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 若 BeanDefinition 指定是需要通过工厂方法进行实例化 Bean
// 比如 @Bean 这个注解配置的 Bean 就会进入这个逻辑
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
// 省略...
}
if (resolved) {
// 省略...
}
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 实例化 bean
return instantiateBean(beanName, mbd);
}
继续深入 AbstractAutowireCapableBeanFactory.instantiateBean(final String beanName, final RootBeanDefinition mbd)
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
// 通过获取到策略实例, 然后调用instantiate()进行实例化
// 不同的策略有不同的实例化方式
// 默认采用 CglibSubclassingInstantiationStrategy
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
// 然后将这个实例封装到 BeanWrapper
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
// 封装一些额外的描述信息到 BeanWrapper 实例
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
// ...
}
}
深入到 SimpleInstantiationStrategy.instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 尝试通过BeanDefinition获取到已经被解析的工厂方法或构造器
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
// 若constructorToUse为空, 就创建一个
if (constructorToUse == null) {
// 通过 BeanDefinition 获取到 Class 实例
final Class<?> clazz = bd.getBeanClass();
// 判断 Class 类型是否是一个接口
// 接口是无法实例化的
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
// 通过 Class 对象获取到待使用的构造方法实例
constructorToUse = clazz.getDeclaredConstructor();
}
// 将这个 constructorToUse 赋值到 BeanDefinition 相应的属性
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 通过工具类提供的方法, 传入构造器实例进行 Bean 的实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
深入 BeanUtils.instantiateClass(constructorToUse)
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
· // 突破访问限制, 比如让private的构造方法可用
ReflectionUtils.makeAccessible(ctor);
// kotlin这一块我们不需要管
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
// 获取到构造方法参数
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
// 这里就是对参数进行一个处理
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
// 这里本质上就调用了反射中Constructor这个类的newInstance()方法进行一个实例化
// 当走到这里, 对象的创建工作就完成了
return ctor.newInstance(argsWithDefaultValues);
}
}
// 省略了异常处理的逻辑
catch (Exception ex) {
//...
}
}
2.2 添加 Bean 实例到缓存
深入 getSingleton() 中调用的 addSingleton(String beanName, Object singletonObject)
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);
}
}
整个代码逻辑非常简单,往一级缓存 singletonObjects 中放入了完整创建好的Bean实例,二级 singletonFactories、三级 earlySingletonObjects 缓存中移除相应的 k-v,并且在 registeredSingletons 容器中添加上相应的 beanName。
到这里,整个实例化 Bean 并获取到相应 Bean 的流程就结束了。
三、总结
整个流程的方法调用栈如下图所示:
逻辑相对来说还是比较复杂的,建议多调试几遍,慢慢地就能够理解执行流程了。
下一篇将对属性注入的逻辑进行详细分析。