前面只是简单说了创建对象的流程,到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);
}
- 先解析class,确保创建对象之前Class已经生成
- 如果配置了factory-method,则用对应的工厂方法创建,进入instantiateUsingFactoryMethod
- 根据参数找到对应构造方法,根据构造方法依赖注入,这里寻找对应的构造方法花费了很多精力,找到构造方法后进入autowireConstructor方法
- 没有参数则用默认构造方法构造instantiateBean
上面创建对象有三个分支:工厂方法、有参构造方法、无参构造方法, 它处理逻辑是相似的,先找到对应生成实例的方法和方法的参数,在根据策略实例化对象, 这两个工作spring又分别委托给了两个角色处理:
- ConstructorResolver,解析生成实例的方法和方法参数,工厂模式解析的是对象的工厂方法,构造方法模式解析的时候对应的构造方法,无参构造方法这边省略了。
- 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的开闭原则,后续要统一看一下。