spring源码分析之bean的创建

本文详细分析了Spring中bean的创建过程,包括不同scope(单例、原型等)的bean实例化,以及核心方法如`createBean()`、`doCreateBean()`和`createBeanInstance()`的执行逻辑。特别讨论了`createBeanInstance()`中的Supplier函数接口、工厂方法和构造函数三种实例化策略,深入探讨了bean的初始化、属性填充和依赖检查等关键步骤。
摘要由CSDN通过智能技术生成

目录

一、不同scope实例创建的简单分析

 1、单例对象创建

  getSingleton(String beanName,ObjectFactory of)方法详解

 2、原型对象创建 

 3、其他Scope范围bean实例创建 

二、创建bean实例的核心流程分析

1、creatBean()方法

2、doCreateBean()方法

3、 createBeanInstance() 

3.1、使用Supplier函数接口进行bean的实例化

3.2、 使用工厂方法进行bean的实例化

3.3、使用构造函数进行bean的实例化


前言:我们在上一篇博文 spring源码分析之bean的加载 中已经介绍了有关spring的bean加载过程中的主要流程,只是在创建不同scope范围的bean实例的过程中留下了伏笔,那么这边博文作者针对其上面博文有关手动创建bean实例进行详细的介绍。

一、不同scope实例创建的简单分析

    先简单补充一下实例创建的代码

   1、单例对象创建

              逻辑代码:单例对象使用beanFactory的重载重载方法 getSingleton(String beanName,ObjectFactory of)

    ObejctFactory是一个接口式接口,这里使用了匿名内部类 调用createBean()方法 具体的创建bean实例的正式该方法。

//创建单例对象代码片段
sharedInstance = getSingleton(beanName, () -> {
try {
	//具体的调用逻辑是调用ObjectFactory其匿名内部类的getObject()方法
	//方法中createBean()方法
	return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
	destroySingleton(beanName);
	throw ex;
	}
});

      getSingleton(String beanName,ObjectFactory of)方法详解

/**
* 创建单例对象
* @param beanName 创建对象的beanName
* @param singletonFactory  具体调用该对象的getObject()方法创建对应的bean实例
* @return 返回创建的对象
*/
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);
	//如果对象为null
	if (singletonObject == null) {
		//则进行单例对象的创建操作
		//判断如果该beanFactory被销毁则抛出异常
		if (this.singletonsCurrentlyInDestruction) {
			throw new BeanCreationNotAllowedException();
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Creating shared instance of singleton bean beanName);
		}
		//单例对象创建之前的回调 默认实现是将其添加到正在创建的列表中
		//表明该对象正在被创建 单例对象 防止多次创建
		beforeSingletonCreation(beanName);
		boolean newSingleton = false;
		//创建保存异常的信息 用于存储创建实例对象的异常信息
		boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
		if (recordSuppressedExceptions) {
			this.suppressedExceptions = new LinkedHashSet<>();
		}
		try {
			//调用ObjectFactory 创建实例对象
			singletonObject = singletonFactory.getObject();
			newSingleton = true;
		}
		catch (IllegalStateException ex) {
			//在创建对象的时候出现异常 可能从别的途径隐式的创建对象 所有从缓存中获取
			// 看看是否有了,破罐子破摔
			singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				throw ex;
			}
			}
			catch (BeanCreationException ex) {
			//添加创建bean实例异常的信息
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
				    }
				}
				throw ex;
			}
			finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				//单例对象创建之前的回调 默认实现将正在创建的该bean标识 
                //从正在创建bean的列表中移除
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				//添加新创建的单例对象到缓存中
				addSingleton(beanName, singletonObject);
			}
		}
		//返回创建的单例对象
		return singletonObject;
	}

 2、原型对象创建 

          创建原型对象的核心逻辑和单例创建实例一致调用createBean()方法

//原型对象创建的代码逻辑
Object prototypeInstance = null;
try {
	//原型对象创建之前的回调
	//主要功能是将创建的beanName 放入prototypesCurrentlyInCreation中
	beforePrototypeCreation(beanName);
	//创建原型对象的方式和创建单例对象的一样 这里不再详述
	prototypeInstance = createBean(beanName, mbd, args);
}
finally {
	//原型对象创建之前的回调
	//主要功能是将创建的beanName从prototypesCurrentlyInCreation移除
	afterPrototypeCreation(beanName);
}

  3、其他Scope范围bean实例创建 

     调用scope的get(String beanName,ObjectFactory of), get()方法中调用ObjectFactory的getObject() 创建对象实例,最终调用和上面的创建bean实例流程一致调用creatBean()方法

//调用scope的get方法,具体的创建的操作是在其第二个匿名参数ObjectFactory
//里面也是调用createBean()
Object scopedInstance = scope.get(beanName, () -> {
	//与原型对象创建之前的回调一致 
	//标记该beanName对应的bean实例对象正在被创建
	beforePrototypeCreation(beanName);
	try {
		//具体创建bean实例的核心代码
		return createBean(beanName, mbd, args);
	}
	finally {
		//与原型对象创建之后的回调一致 
		//移除beanName对应的bean实例从标记中
		afterPrototypeCreation(beanName);
	}
});


//scope 获取对象的
public Object get(String name, ObjectFactory<?> objectFactory) {
    //先从缓存中获取对应的bean实例 如果没有则调用ObjectFactory的getObject()方法
    //getObject()方法中的实现是上面匿名内部类的createBean()方法
    Map<String, Object> scope = (Map)this.threadScope.get();
    Object scopedObject = scope.get(name);
    if (scopedObject == null) {
       scopedObject = objectFactory.getObject();
        scope.put(name, scopedObject);
    }
    return scopedObject;
}

 对于上面三种类型bean实例创建,各有不同点,但是最终都是调用相同的createBean()来进行实例的创建。下面我们来分析三种创建bean实例的核心代码createBean()方法。

二、创建bean实例的核心流程分析

    1、creatBean()方法

//根据RootBeanDefinition 创建对应的bean实例
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;
	//1、解析beanDefinition中获取其中的class属性
    //如果beanDefinition中没有填充class属性
	//填充对应的RootBeanDefinition 的BeanClass
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass()
        && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	try {
	  //2、在beans.xml 中replace-method、lookup 配置 
      //会被解析到BeanDefinition的MethodOverride中
	  //标记BeanDefintion中的某些MethodOverride 只有一个方法 标明该方法没有重载方法
	  //在进行methodOverrides实例化的时候避免参数检查的开销
	  mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
	  throw new BeanDefinitionStoreException(ex);
	}
	try {
		//3、通过应用bean的后置处理器 返回一个代理对象而非目标对象,
        //此处是我们常用的AOP功能的实现
		//这里有一个短路操作 如果代理对象存在则直接返回代理对象 不在做后续的操作
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(ex);
	}

	try {
		//4、对于普通的bean 实例执行真正的创建bean实例的逻辑
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
        //返回bean实例对象
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) 			 
          throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(ex);
	}
}

     上面代码的主要逻辑如下:

  1.  解析beanDefinition中获取其中的class属性,如果beanDefinition中没有填充class属性,填充对应的RootBeanDefinition的class属性。
  2. 在beans.xml 中replace-method、lookup 配置 会被解析到BeanDefinition的MethodOverride中,bean实例化的时候如果检测道存在MethodOverride属性,会动态的为当前bean生成代理并使用对应的拦截器为bean做增强处理。同时标记如果BeanDefintion中的某些MethodOverride只有一个方法标明该方法没有重载方法,避免参数检查的开销。 
  3. public void prepareMethodOverrides() throws BeanDefinitionValidationException {
       //判断beanDefintion是否有MethodOverrides
       if (hasMethodOverrides()) {
    	  getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
       }
    }
    protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    	//获取class中 方法名对应的重载方法的个数
    	int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
    	if (count == 0) {
    		throw new BeanDefinitionValidationException();
    	}
    	//如果重载方法个数为1 则说明该方法没有重载方法 设置MethodOverride 的重载标识为false
    	else if (count == 1) {
    		// Mark override as not overloaded, to avoid the overhead of arg type checking.
    		mo.setOverloaded(false);
    	}
    }
  4. 通过应用bean的后置处理器 返回一个代理对象而非目标对象,此处是我们常用的AOP功能的实现。这里有一个短路操作 如果代理对象存在则直接返回代理对象不在做后续的操作。
  5. //应用后置处理器,对bean实例进行代理增强 我们的AOP代理增强也是在该处来进行实现
    @Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    	Object bean = null;
    	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    			//获取bean的class实例
    			Class<?> targetType = determineTargetType(beanName, mbd);
    			if (targetType !&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值