实例化
AbstractApplicationContext->refresh():
finishBeanFactoryInitialization(beanFactory);
AbstractApplicationContext->finishBeanFactoryInitialization():
beanFactory.preInstantiateSingletons();
DefaultListableBeanFactory->preInstantiateSingletons():
// 对beanDefinitionNames遍历
for (String beanName : beanNames) {
// 该RootBeanDefinition从mergedBeanDefinitions取出
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 只对单例和没有@Lazy注解的bean实例化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是否实现了FactoryBean接口
if (isFactoryBean(beanName)) {
......
} else {
getBean(beanName);
}
}
AbstractBeanFactory->getBean():
return doGetBean(name, null, null, false);
AbstractBeanFactory->doGetBean():
// 如果name前缀有&的话会去掉
final String beanName = transformedBeanName(name);
// 从singletonObjects取出,如果有值,说明已经实例化完成
Object sharedInstance = getSingleton(beanName);
......
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 如果bean声明了依赖,会先实例化它的依赖
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
......
}
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 如果作用域是原型的话,每次调用都会生成
......
} else {
// 处理其他作用域
.....
}
从上面代码可以得到以下结论:
- 无论什么类型的BeanDefinition,实例化的时候都会转为RootBeanDefinition
- 启动阶段,IoC容器只会对没有@Lazy注解的单例bean实例化
- 对于bean不同的作用域有不同的处理方式,成员变量
singletonObjects保证了单例bean在容器中只会有一个实例化对象
后续调用最终进入AbstractAutowireCapableBeanFactory->doCreateBean()方法,在这之前还有一些不可遗漏的小细节:
- 注意到
DefaultSingletonBeanRegistry->getSingleton()方法有beforeSingletonCreation(beanName)和afterSingletonCreation(beanName),这两句与循环依赖有关系。 AbstractAutowireCapableBeanFactory->createBean()有Object bean = resolveBeforeInstantiation(beanName, mbdToUse),它的作用是给后置处理一个返回代理的机会,一般返回都为空,这里会执行后置处理器的postProcessBeforeInstantiation()方法,如果有AnnotationAwareAspectJAutoProxyCreator这个后置处理器,此时将会提前解析AoP方法。
@Autowired依赖注入
/**
* 这一段代码的作用就是提前找到依赖注入的字段、初始化方法、销毁方法
* 1.放到不同后置处理器的缓存map中
* 2.设置bd的externallyManaged...属性值
* 3.最后将bd的postProcessed置为true
*/
AbstractAutowireCapableBeanFactory->doCreateBean():
// 选取最合适的构造方法实例化对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
AbstractAutowireCapableBeanFactory->applyMergedBeanDefinitionPostProcessors():
// 遍历IoC容器的beanPostProcessors,当为autowiredAnnotationBeanPostProcessor时
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
AutowiredAnnotationBeanPostProcessor->postProcessMergedBeanDefinition():
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
AutowiredAnnotationBeanPostProcessor->findAutowiringMetadata():
// 第一次进入,metadata肯定为null,所以肯定会走到这一步
// 方法的主要作用就是反射遍历field字段,找出所有带@Autowired或@Value的字段,然后返回
metadata = buildAutowiringMetadata(clazz);
// injectionMetadataCache存入,便于下一次从缓存中获取
this.injectionMetadataCache.put(cacheKey, metadata);
/**
*这一段代码的作用就是依赖注入
*/
AbstractAutowireCapableBeanFactory->doCreateBean():
populateBean(beanName, mbd, instanceWrapper);
AbstractAutowireCapableBeanFactory->populateBean():
// 如果自动注入模式是AUTOWIRE_BY_NAME或者AUTOWIRE_BY_TYPE的话,实例化要自动注入的对象
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
// --3
......
}
// 遍历IoC容器的beanPostProcessors,这里分析当为autowiredAnnotationBeanPostProcessor时
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
......
// 经过自动注入模式过程后,有要自动注入的对象,则调用set方法注入
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
AutowiredAnnotationBeanPostProcessor->postProcessProperties():
// 前面已存入,此处直接取就是了
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
InjectionMetadata->inject():
// elementsToIterate是所有@Autowired的字段
for (InjectedElement element : elementsToIterate) {
// element封装了需要注入的字段
element.inject(target, beanName, pvs);
}
AutowiredAnnotationBeanPostProcessor->AutowiredFieldElement->inject():
// --1
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
......
// 利用反射完成注入
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
DefaultListableBeanFactory->resolveDependency(): // --1
// --2 是否懒加载
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
DefaultListableBeanFactory->doResolveDependency()
// IoC候选和初筛候选
matchingBeans = findAutowireCandidates(beanName, type, descriptor);
......
// 当beanName不止一个的时候,最终候选
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
}
......
// 然后实例化beanName
// instanceCandidate是一个反射类,执行完if语句后成为一个对象实例
if (instanceCandidate instanceof Class) {
// 调用的beanFactory.getBean(beanName)方法
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
--3处,得到autowireMode自动注入模式属性值,如果是AUTOWIRE_BY_NAME的话,调用getBean(String name)实例化,如果是AUTOWIRE_BY_TYPE的话,流程与--1一样。关于它要自动注入的对象参见AbstractBeanDefinition属性说明中的autowireMode 自动注入模式。
--2处,如果字段使用懒加载注解的话,直接返回代理了,这种情况暂时不考虑,关于懒加载的后续说明请点击此处。
总结:
- 对bean分析,提前获取需要注入的字段
- 依赖注入方法中,依次遍历,根据字段的类型、名称或是bean信息反推beanName,然后实例化
- 利用反射field.set()方法,完成注入
根据@Autowired注解获取bean举例:
- IoC候选由field.getType()推断而来,调用的是
getBeanNamesForType(@Nullable Class<?> type)方法
| 情况 | IoC候选 | 初筛候选 | 最终结果 | 说明 |
|---|---|---|---|---|
| @Autowired private Demo demo1 | demo | \ | demo | IoC候选就一个 |
| @Autowired private Demo demo | demo1,demo2 | demo1,demo2 | 报错 | 找到多个 |
| @Autowired private Demo demo | @Primary demo1,demo2 | demo1,demo2 | demo1 | 由@Primary注解决定 |
| @Autowired private Demo demo1 | demo1,demo2 | demo1,demo2 | demo1 | 最终由field.getName() 决定 |
| @Autowired @Qualifer("demo1") private Demo demo1 | demo1,demo2 | demo1 | demo1 | 初筛由@Qualifer("demo1") 决定 |
| @Autowired @Qualifer("demos") private Demo demo1 | demo1 | 空 | 报错 | 找不到demos的候选名称 |
举一反三:
1.对于@Resource,@Value的注入,都是在populateBean()方法中完成的,只不过是不同的Bean后置处理器起的作用而已
2.如果是通过构造器注入的,会找到对应构造器,然后使用反射方法constructor.newInstance()完成实例化。构造器的参数同样经历总结中1、2的步骤
附录:beanFactory常用方法
getBean(String name)根据beanName获取bean,与实例化过程相同getBeanNamesForType(@Nullable Class<?> type)根据beanClass返回beanName数组。如果有缓存则直接取缓存,否则遍历beanDefinitionNames和manualSingletonNames,找到beanName对应的beanClass,如果是目录类或者目标类的子类则添加getBean(String name, Class<T> requiredType)先根据beanName获取bean,然后判断该bean是否为requiredType类或子类,如果是的话返回,否则抛出异常getBean(Class<T> requiredType)根据beanClass获取bean。先调用getBeanNamesForType(@Nullable Class<?> type)获取beanClass对应的beanName,然后调用getBean(String name, Class<T> requiredType)返回beangetBeansOfType(@Nullable Class<T> type)根据beanClass获取beanName和bean。先调用getBeanNamesForType(@Nullable Class<?> type)获取beanClass对应的beanName,然后调用getBean(String name)得到bean,将beanName与bean放入map中,最后返回mapgetBeanNamesForAnnotation(Class<? extends Annotation> annotationType)根据annotationClass获取beanName数组。每次都遍历beanDefinitionNames和manualSingletonNames,如果beanClass声明注解及子注解有符合annotationClass的注解则添加getBeansWithAnnotation(Class<? extends Annotation> annotationType)根据annotationClass获取bean数组。先调用getBeanNamesForAnnotation(Class<? extends Annotation> annotationType)获取注解对应的beanName,然后调用getBean(String name)获取bean
registerSingleton(String beanName, Object singletonObject)手动注入IoC容器单例bean,如果beanName已在容器中,会报错。若beanDefinitionMap不存在则添加到manualSingletonNamesgetBeanPostProcessors()获取后置处理器集合,返回的是成员变量beanPostProcessorsaddBeanPostProcessor(BeanPostProcessor beanPostProcessor)手动添加后置处理器registerBeanDefinition(String beanName, BeanDefinition beanDefinition)手动注入到bdm和bdn