接着上一部分的内容,我们继续来研究getBean方法的源码
上一讲我们讲到了getSingleton方法,接下来我们来看getObjectForBeanInstance(sharedInstance, name, beanName, null);这句代码
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// 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.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean> factory = (FactoryBean>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
可以看到这个方法其实是获取缓存中的bean实例,但是它还判断了bean是factoryBean类型的情况和bean是factoryBean本身的情况,因为factoryBean本身也是一个bean,只不过它有些特殊的功能,关于factoryBean,其实和BeanFactory的概念是很容易混淆的,有机会我还会写一篇关于factoryBean和BeanFactory的区别,现在先不讨论。
接下来,如果缓存中没有数据,那么会到上一层的beanFactory中去试图获得bean,其实最终还是会到这个doGetBean方法里来,如果上一层的beanFactory中拿不到bean,那么接下来会来到这段代码,这段代码非常的重要
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//检查是否有depends on
// Guarantee initialization of beans that the current bean depends on.
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 {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建bean实例
// Create bean instance.
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.
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);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
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) {
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;
}
这里面这句代码final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
就是去合并parent的属性进来。RootBeanDefinition是个什么类呢,我从网上找到了一个人的解释,我觉得挺到位的,贴出来给大家看
//简单的说:在多继承体系中,RootBeanDefinition代表的是当前初始化类的父类的BeanDefinition 若没有父类,那就是它自己嘛
public class RootBeanDefinition extends AbstractBeanDefinition {
//BeanDefinitionHolder存储有Bean的名称、别名、BeanDefinition
@Nullable
private BeanDefinitionHolder decoratedDefinition;
// AnnotatedElement 是java反射包的接口,通过它可以查看Bean的注解信息
@Nullable
private AnnotatedElement qualifiedElement;
//允许缓存
boolean allowCaching = true;
//从字面上理解:工厂方法是否唯一
boolean isFactoryMethodUnique = false;
//封装了java.lang.reflect.Type,提供了泛型相关的操作
@Nullable
volatile ResolvableType targetType;
//缓存class,表明RootBeanDefinition存储哪个类的信息
@Nullable
volatile Class> resolvedTargetType;
//缓存工厂方法的返回类型
@Nullable
volatile ResolvableType factoryMethodReturnType;
/** Common lock for the four constructor fields below */
final Object constructorArgumentLock = new Object();
//缓存已经解析的构造函数或是工厂方法,Executable是Method、Constructor类型的父类
@Nullable
Executable resolvedConstructorOrFactoryMethod;
//表明构造函数参数是否解析完毕
boolean constructorArgumentsResolved = false;
//缓存完全解析的构造函数参数
@Nullable
Object[] resolvedConstructorArguments;
//缓存待解析的构造函数参数,即还没有找到对应的实例,可以理解为还没有注入依赖的形参
@Nullable
Object[] preparedConstructorArguments;
/** Common lock for the two post-processing fields below */
final Object postProcessingLock = new Object();
//表明是否被MergedBeanDefinitionPostProcessor处理过
boolean postProcessed = false;
//在生成代理的时候会使用,表明是否已经生成代理
@Nullable
volatile Boolean beforeInstantiationResolved;
//实际缓存的类型是Constructor、Field、Method类型
@Nullable
private Set externallyManagedConfigMembers;
//InitializingBean中的init回调函数名——afterPropertiesSet会在这里记录,以便进行生命周期回调
@Nullable
private Set externallyManagedInitMethods;
//DisposableBean的destroy回调函数名——destroy会在这里记录,以便进行生命周期回调
@Nullable
private Set externallyManagedDestroyMethods;
//===========方法(只例举部分)
// 由此看出,RootBeanDefiniton是木有父的
@Override
public String getParentName() {
return null;
}
@Override
public void setParentName(@Nullable String parentName) {
if (parentName != null) {
throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
}
}
// 拿到class类型
@Nullable
public Class> getTargetType() {
if (this.resolvedTargetType != null) {
return this.resolvedTargetType;
}
ResolvableType targetType = this.targetType;
return (targetType != null ? targetType.resolve() : null);
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
return new RootBeanDefinition(this);
}
}
在经过getMergedLocalBeanDefinition(beanName)这个方法得到mbd之后,会去检查mbd中有没有dependsOn,因为需要控制bean的加载顺序,如果有dependsOn注解的话要先注册被依赖的那个bean,然后再getBean,如果没有dependsOn注解,那就是最普通的bean,那就要走到
创建bean实例的代码段了
//这里创建完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);
调用createBean方法最后会来到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])这个方法中
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 处理 lookup-method 和 replace-method 配置,Spring 将这两个配置统称为 override method
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 在 bean 初始化前应用后置处理,如果后置处理返回的 bean 不为空,则直接返回
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
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 {
// 调用doCreateBean 创建bean,关键中的关键,但是这个方法很复杂
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
这个方法中,最重要的一句代码是Object beanInstance = doCreateBean(beanName, mbdToUse, args);这句代码是创建bean实例的代码,这个方法非常复杂,会涉及到bean的循环引用,属性的注入,后置处理器的使用等等,有关这些不在本次源码解读的范围内,就不详细去讲了,我就把代码贴出来简单讲解一下创建bean的实例主要分哪几个步骤
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/**
* 创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回。
* createBeanInstance中包含三种创建 bean 实例的方式:
* 1. 通过工厂方法创建 bean 实例
* 2. 通过构造方法自动注入(autowire by constructor)的方式创建 bean 实例
* 3. 通过无参构造方法方法创建 bean 实例
*
* 若 bean 的配置信息中配置了 lookup-method 和 replace-method,则会使用 CGLIB
* 增强 bean 实例。关于lookup-method和replace-method后面再说。
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//设置属性,非常重要
populateBean(beanName, mbd, instanceWrapper);
//执行后置处理器,aop就是在这里完成的处理
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
到了这里,其实大家就可以看我之前的《一道面试题引发的spring源码阅读》这篇文章了,这篇文章就是从instanceWrapper = createBeanInstance(beanName, mbd, args);这个方法开始讲起的,调用过这个方法以后,实际上就已经可以拿到bean了,只不过这个bean是被包装类给包装起来的bean,再然后就是设置属性,执行后置处理器了,执行完后置处理器,整个bean就算实例化完成了,最后返回到getBean方法,加一个强制转换就可以得到对象了。
总结
经过两篇文章的分析,相信大家已经基本清楚了getBean方法的执行流程和调用的那些方法和方法的含义,同时也熟悉了spring了代码风格,就是不断的嵌套调用很多的继承加上很多的工厂很多的重载方法,有时间的话我还会解读spring如何解决bean的循环引用,beanFactory和FactoryBean的区别,属性注入,bean后置处理器等等的源码,希望大家多多关注多多支持,谢谢大家。