Spring源码阅读-BeanFactory-对象创建注入doCreateBean

前面只是简单说了创建对象的流程,到doCreateBean中才进入到真实创建对象的部分,去掉一些异常判断,一个对象的创建主要有以下几部分,先看总代码,再依次分析:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		//1. 创建对象
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

	//...

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		//2. 填充对象   这个里面解析了依赖的bean
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			//3. 初始化方法
			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);
		}
	}

	//...

	// Register bean as disposable.
	try {
		//4. 注册销毁方法
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	} catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature",
				ex);
	}
	return exposedObject;
}

一 创建对象

这步就是根据class生成对象,对象内存空间就是这边完成的,最终把BeanDefinition转换成BeanWrapper,spring根据创建对象的方法不同走了不同的分支逻辑,看createBeanInstance代码流程:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
	// Make sure bean class is actually resolved at this point.
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

	//...
	
	//工厂方法创建对象
	if (mbd.getFactoryMethodName() != null) {
		//factory-method, 方法需要时static型的
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// Shortcut when re-creating the same bean...
	boolean resolved = false;
	boolean autowireNecessary = false;
	//注意这里的args是通过getBean传的,不传为空
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			//如果构造方法已经解析好则获取默认,缓存作用,后面解析出来会存放进来
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	//如果构造方法已经解析
	if (resolved) {
		if (autowireNecessary) {
			return autowireConstructor(beanName, mbd, null, null);
		} else {
			return instantiateBean(beanName, mbd);
		}
	}

	//获取对应的有参构造方法
	// Need to determine the constructor...
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR
			|| mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// 没有解析到有参构造方法则使用默认无参构造方法
	// No special handling: simply use no-arg constructor.
	return instantiateBean(beanName, mbd);
}
  1. 先解析class,确保创建对象之前Class已经生成
  2. 如果配置了factory-method,则用对应的工厂方法创建,进入instantiateUsingFactoryMethod
  3. 根据参数找到对应构造方法,根据构造方法依赖注入,这里寻找对应的构造方法花费了很多精力,找到构造方法后进入autowireConstructor方法
  4. 没有参数则用默认构造方法构造instantiateBean

上面创建对象有三个分支:工厂方法、有参构造方法、无参构造方法, 它处理逻辑是相似的,先找到对应生成实例的方法和方法的参数,在根据策略实例化对象, 这两个工作spring又分别委托给了两个角色处理:

  1. ConstructorResolver,解析生成实例的方法和方法参数,工厂模式解析的是对象的工厂方法,构造方法模式解析的时候对应的构造方法,无参构造方法这边省略了。
  2. InstantiationStrategy,实例化对象的策略,无overrides走反射,有overrides用cglib生成

二 填充对象

这个里面就是设置依赖属性了,看下面精简过的代码:

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
	//这个是配置文件中的,后面根据策略获取非配置文件中的
	PropertyValues pvs = mbd.getPropertyValues();

	//...

	//可以在bean配置里面设置autowire类型
	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME
			|| mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

		//根据名称解析,配置文件配置autowire="byName"
		// Add property values based on autowire by name if applicable.
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		//根据类型解析
		// Add property values based on autowire by type if applicable.
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}

		pvs = newPvs;
	}

	//...
	
	//设置属性
	applyPropertyValues(beanName, mbd, bw, pvs);
}

可以在配置文件中用property标签配置,可以用autowire="byName(byType)"属性配置,最终获取的需要依赖对象都放到PropertyValues中,后通过applyPropertyValues设置依赖对象。注意:这里的autowire标签属性要跟@Autowired区分,@Autowired是2.5以加入通过注解简化配置的功能,这个后续再看。

三 初始化对象

这步首先把Aware类型的注入了:

private void invokeAwareMethods(final String beanName, final Object bean) {
	if (bean instanceof Aware) {
		//子类判断
		if (bean instanceof BeanNameAware) {
			//beanName设置
			((BeanNameAware) bean).setBeanName(beanName);
		}
		if (bean instanceof BeanClassLoaderAware) {
			//classLoader设置
			((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
		}
		if (bean instanceof BeanFactoryAware) {
			//bean工厂设置
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

其次,调用初始化方法,如果实现了InitializingBean则执行afterPropertiesSet方法,如果有自定义方法则调用自定义方法。

四 注册销毁方法

如果单例情况并且有销毁方法,则把bean注册到对应的销毁bean集合,在对象工厂shutdown的时候调用,如果是非原形的其他scope则由该scope自定义销毁策略。

 

补充:在上面这四个步骤之间穿插着一些BeanPostProcessors的调用,这是spring的开闭原则,后续要统一看一下。

 

转载于:https://my.oschina.net/chengxiaoyuan/blog/822454

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值