目录
前言
一、populateBean - 概述
二、populateBean - 详解
2.1. 属性填充判断
2.2、自动装配 :autowiring自动装配的
2.2.1、自动装配 - autowireByName
2.2.2、 自动装配 - autowireByType
2.3、排除规则 - unsatisfiedNonSimpleProperties
3、@Autowired 和 @Resource 的注入工作
3.1、第六次调用后置处理器 InstantiationAwareBeanPostProcessor#postProcessProperties
3.2、CommonAnnotationBeanPostProcessor#postProcessPropertyValues
3.3、AutowiredAnnotationBeanPostProcessor #postProcessPropertyValues
3.4、需要依赖注入的对象 DefaultListableBeanFactory#resolveDependency
4. applyPropertyValues
三、总结
本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。
我们在上一篇文章:spring bean生命周期二---Spring Bean实例化( Instantiation)阶段 中完成了bean的实例化过程 ,但是属性内容还没有注入,本文就是将bean的属性进行注入的过程。
我们这里先整体过一遍代码,后面进行每一步的详细解读。
// AbstractAutowireCapableBeanFactory#populateBean
// beanName : bean 的name
// mbd : bean的定义信息
// bw : bean实例的包装类型,里面有bean的实例
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
没有属性抛出异常
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
//
boolean continueWithPropertyPopulation = true;
//mbd.isSynthetic() 合成类
//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
//这个是程序员在 bd中 写入的属性rootBeanDefinition.getPropertyValues().add("type","男的");
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据Bean名称进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据Bean类型进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//对非autowiring的属性进行依赖注入处理
// 后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
//TODO 获取的bean所有后置处理器找到 所有需要注入的属性
// 这里会进行 @Autowired 和 @Resource 的注入工作
// 属性填充InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//下面是完成属性注入的
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依赖检查,对应 depends-on 属性,3.0 已弃用
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
4. 将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
从上看下来,整个流程如下:
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
方法,可以决定程序是否继续进行属性填充。只要有一个 InstantiationAwareBeanPostProcessor
返回false,都会终止属性填充的过程。这个过程属于实例化 后置阶段上上文已经描述过了InstantiationAwareBeanPostProcessor#postProcessProperties
方法,对属性获取完毕填充前对属性的再次处理。有两个实现类型 :1、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的
2、AutowiredAnnotationBeanPostProcessor 中的实现类 处理 @Autowired 注解的
propertyValues
中的属性填充至 BeanWrapper
中。在这里方法里按照如下顺序调用了后处理器
这个的上文中已经描述过了这里就简单贴出代码
//mbd.isSynthetic() 合成类
//todo 第五次---判断属性是否填充:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
// 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
如下,这里调用了InstantiationAwareBeanPostProcessor
#postProcessAfterInstantiation
方法来决定是否继续注入属性。该方法正常返回true。如果返回false 则将取消对此bean调用任何后续的InstantiationAwareBeanPostProcessor
方法。
在下面这段代码中,对 autowiring自动装配中根据名称或类型自动注入的种类进行自动装配。
2. 自动装配 :autowiring自动装配的。根据名称或类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据Bean名称进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据Bean类型进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
这一段代码的目的是,如果bean在声明的时候指定了自动注入类型是 byName或者byType,则会根据这个规则,对 bean内部的排除某些特定的属性(排除规则后面详解), 进行byName 或者 byType的自动装配。
//根据名称对属性进行自动依赖注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符串,URL等都是简单属性)进行处理
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//如果Spring IOC容器中包含指定名称的Bean
if (containsBean(propertyName)) {
//调用getBean方法向IOC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入
Object bean = getBean(propertyName);
//为指定名称的属性赋予属性值
pvs.add(propertyName, bean);
//指定名称属性注册依赖Bean名称,进行属性依赖注入
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
可以看到,byName 的处理逻辑很简单,一句话概括,获取需要注入的bean然后递归调用getBean获取bean进行注入。 关于 unsatisfiedNonSimpleProperties
方法在后面有讲解。
byType 的装配和 byName 对我们感觉来说似乎没什么差异,但是在实际实现上却截然不同,代码也复杂的多。具体代码如下:
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取用户定义的类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//存放解析的要注入的属性
Set autowiredBeanNames = new LinkedHashSet<>(4);
//对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符
//URL等都是简单属性)进行处理
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
//获取指定属性名称的属性描述器
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
//不对Object类型的属性进行autowiring自动依赖注入
if (Object.class != pd.getPropertyType()) {
//获取属性的setter方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
//检查指定类型是否可以被转换为目标对象的类型
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
//创建一个要被注入的依赖描述
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//根据容器的Bean定义解析依赖关系,返回所有要被注入的Bean对象
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
//为属性赋值所引用的对象
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
//指定名称属性注册依赖Bean名称,进行属性依赖注入
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
//释放已自动注入的属性
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
下面提两点 :
关于 registerDependentBean 方法,我们在之前的文章中有过解释,详阅 Spring 源码分析三 :bean的加载① - doGetBean概述
这里面的主要的逻辑被封装到了DefaultListableBeanFactory#resolveDependency
方法的具体实现我们在后继查看。目前我所知另外调用地方:
AutowiredAnnotationBeanPostProcessor#postProcessProperties
中注入处理 @Autowired 注入的时候也调用了该方法ConstructorResolver#autowireConstructor
在 resolveAutowiredArgument( methodParam, beanName, autowiredBeanNames, converter, fallback);
时也调用了该方法。在autowireByName
和 autowireByType
方法中,都有如下一行代码
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
在 unsatisfiedNonSimpleProperties
方法中,对Bean 的属性进行了过滤,得到了需要自动装配的属性。我们来详细看看里面的内容。
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set result = new TreeSet<>();
// 获取bean 的property 属性
PropertyValues pvs = mbd.getPropertyValues();
// 获取 bw 中的属性描述
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
// if pd属性具有set方法 && 依赖检查中没有被忽略 && 没有被配置成 property 属性 && 不是简单类型
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
// 添加到需要装配的集合中
result.add(pd.getName());
}
}
// 返回需要自动装配的bean集合
return StringUtils.toStringArray(result);
}
可以看到过滤条件
这里只要时候 InstantiationAwareBeanPostProcessor#postProcessProperties 后置处理器处理
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
//TODO 获取的bean所有后置处理器找到 所有需要注入的属性
// 这里会进行 @Autowired 和 @Resource 的注入工作
// 属性填充InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//下面是完成属性注入的
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 如果postProcessProperties 返回null,再调用 postProcessPropertyValues这个过时的方法
if (pvs == null) {
return;
}
}
}
}
这里通过 InstantiationAwareBeanPostProcessor
#postProcessPropertyValues
方法完成了属性的注入。
1、AutowiredAnnotationBeanPostProcessor #postProcessPropertyValues
中的实现类 处理 @Autowired 注解和@Value 注解的自动注入功能。
2、CommonAnnotationBeanPostProcessor#postProcessPropertyValues
中的实现类 处理 @Resource注解、@PostConstruct等通用注解。
postProcessPropertyValues
//处理属性值
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
//获取@Resource注解中配置的属性值元数据
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
获取@Resource注解中配置的属性值元数据
这里主要是对 @Resource 进行注入findResourceMetadata在MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition的时候执行过.
所以这里, 大概率是从缓存中拿取结果, 然后进行注入操作. 事实上, 也确实如此.
/获取@Resource注解中配置的属性值元数据
private InjectionMetadata findResourceMetadata(String beanName, final Class> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
//首先从容器缓存中查找
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildResourceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
metadata.inject(bean, beanName, pvs);
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//
Collection checkedElements = this.checkedElements;
Collection elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
element.inject(target, beanName, pvs);的实现类有三个
这里最终会调用本类中的方法:
org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject 方法
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
//这里处理通过字段注入
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
//这里处理通过方法注入
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
postProcessPropertyValues
大概逻辑是,获取被 @Autowired 修饰的 属性或者方法,如果是属性,则通过getBean 获取bean并注入,如果是方法,则获取方法参数后,invoke 方法(调用该方法,因为我们一般写的都是set方法,给属性注入赋值)。
//处理类中的属性
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//获取指定类中autowire相关注解的元信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//对Bean的属性进行自动注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
这里主要是对 @Autowired 和 @Value 进行注入的. InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
findAutowiringMetadata在MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition的时候执行过.
所以此处, 是从缓存中拿取结果, 然后进行注入操作.
最终会调用本类中的方法:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
//对字段进行注入
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//获取注入元素对象
Field field = (Field) this.member;
Object value;
//如果当前对象在容器中被缓存 默认为false.
if (this.cached) {
//根据Bean名称解析缓存中的字段值
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
//如果当前对象没有被容器缓存
else {
//创建一个字段依赖描述符
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
//获取容器中的类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//根据容器中Bean定义,解析指定的依赖关系,获取需要依赖注入的对象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
//线程同步,确保容器中数据一致性
synchronized (this) {
//如果当前对象没有被容器缓存
if (!this.cached) {
//获取到了当前对象的依赖对象,并且required属性为true
if (value != null || this.required) {
this.cachedFieldValue = desc;
//为指定Bean注册依赖Bean
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
//如果容器中有指定名称的Bean对象
if (beanFactory.containsBean(autowiredBeanName)) {
// 依赖对象类型和字段类型匹配,默认按类型注入
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
//创建一个依赖对象的引用,同时缓存
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
//如果获取的依赖关系为null,且获取required属性为false
else {
//将字段值的缓存设置为null
this.cachedFieldValue = null;
}
//容器已经对当前字段的值缓存
this.cached = true;
}
}
}
//如果字段依赖值不为null
if (value != null) {
//显式使用JDK的反射机制,设置自动的访问控制权限为允许访问
ReflectionUtils.makeAccessible(field);
//TODO 为Bean对象的字段设置值 完成了属性填充
field.set(bean, value);
}
}
}
根据容器中Bean定义,解析指定的依赖关系,获取需要依赖注入的对象。这里是很重要的方法在很多地方都使用到
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 针对不同类型的不同处理
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
//延迟加载
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
//
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
//ToDO 这个一般为空 这个是特殊情况 处理bean是否懒加载,如果懒加载,创建一个代理对象注入bean
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 下面是正常情况
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
上面的逻辑比较清晰,对一些特殊的类型进行特殊处理,一般的通用处理都会调用 doResolveDependency
方法。这里我们不去关注特殊类型的处理,下面再来看看DefaultListableBeanFactory#doResolveDependency
方法,代码如下。
DefaultListableBeanFactory#doResolveDependency
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
//非正常情况
// 尝试获取缓存
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
// 存在缓存直接返回
return shortcut;
}
//获得需要注入属性的类型
Class> type = descriptor.getDependencyType();
// 取值@Value注解中的value属性中的值,这里取出的值是未经修改的值,即带有 ${} 标签的值。如果descriptor未被@Value标注,则返回null
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
// 到这里说明属性被 @Value 注解修饰了,这里是解析 @Value 注解的逻辑
// 如果value不为nul
if (value instanceof String) {
// 处理占位符如${},做占位符的替换(不解析SP EL表达式)
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
//解析SP EL(如#{})
value = evaluateBeanDefinitionString(strVal, bd);
}
// 类型转换,把解析出来的结果转成type类型
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
//TODO 对集合类型进行处理,包括,Array、Collection、Map。后面详解
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
// 如果解析出来集合类型,则直接返回
return multipleBeans;
}
//调用查找所有类型为type的实例,存放在matchingBeans
// (在 resolveMultipleBeans 方法中也是核心也是调用该方法)。下面详解
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//TODO 这个是处理 这个是根据 类型找到多个bean(也就是实现类有多个)
// 如果有多个bean 则在按照名字来匹配多个bean 找出来一个bean 用来注入
if (matchingBeans.size() > 1) {
// 按以下顺序,找到符合条件的就直接返回
// 1. 挑选出被标识为primary的bean
// 2. 挑选标识了@Priority,且先级级最高的bean。可以不标识,一旦标识,不允许同一优先级的存在
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
// 非集合类,找到了多个符合条件的Bean,抛出异常
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
//根据名字从 根据类型的获得的matchingBeans 找到bean
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
// 如果只找到了唯一匹配的元素,则直接使用
Map.Entry entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
// 将待装配的Bean名称放入autowiredBeanNames集合里
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
// 这里又去调用 getBean 方法去获取bean
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
// 如果 result 是 NullBean类型,且 required = true,则抛出异常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
// 类型校验,确保类型与解析出来的Bean实例能够匹配
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
DefaultListableBeanFactory#resolveMultipleBeans
这个方法是用来处理 数组、Collection、Map 类型的注入。具体实现如下:
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) {
final Class> type = descriptor.getDependencyType();
// 如果是 StreamDependencyDescriptor 类型,则返回流的形式
if (descriptor instanceof StreamDependencyDescriptor) {
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream
可以看到的是,如果是集合类型,内部的核心方法也是 findAutowireCandidates
方法。所以下面还是来看 DefaultListableBeanFactory#findAutowireCandidates
方法。
DefaultListableBeanFactory#findAutowireCandidates
protected Map findAutowireCandidates(
@Nullable String beanName, Class> requiredType, DependencyDescriptor descriptor) {
// 根据 Class 类型,找到对应的候选beanName,
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map result = new LinkedHashMap<>(candidateNames.length);
// 这里我们一般不会涉及。如果注入的是 resolvableDependencies key类型,则会装配成value类型
for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 遍历候选的beanName
for (String candidate : candidateNames) {
// 不是自引用 && 允许被注入(autowire-candidate 标签指定)
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 将结果添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 如果目前找到的匹配的bean集合为空
if (result.isEmpty()) {
// Array || Collection || Map 。即是否表示多个bean的集合类型
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
// 非自引用 && 允许被注入 && (非集合类 || 解析 @Qualifier 注解或者 javax.inject.Qualifier类成功)
// 这里开始分析解析的属性是否被 @Qualifier 注解或者 javax.inject.Qualifier类 限定符限定了
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 如果还没找到 && 非集合类
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
// 将自我引用视为最后一步。判断是不是自己引用自己
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
...
private void addCandidateEntry(Map candidates, String candidateName,
DependencyDescriptor descriptor, Class> requiredType) {
// 根据类型判断,如果是MultiElementDescriptor,获取后保存到候选列表中
if (descriptor instanceof MultiElementDescriptor) {
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
if (!(beanInstance instanceof NullBean)) {
candidates.put(candidateName, beanInstance);
}
}
// 如果 单例缓存中存在 || 是 StreamDependencyDescriptor 的类型 && order = true
else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
// 调用了beanFacotory.getBean 方法获取bean
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
// 保存起来
candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
// getType 调用了beanFacotory.getBean 方法
candidates.put(candidateName, getType(candidateName));
}
}
这里提两点:
这里需要注意 resolvableDependencies
。其在 DefaultListableBeanFactory#resolvableDependencies
定义如下,其作用是,当一些其他的类需要装配key类型的bean时,实际装配的类型是key对应的value 类型。
/** Map from dependency type to corresponding autowired value. */
// key 是映射值,value是实际注入值
private final Map, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
在 Spring默认的代码中,仅仅有八个元素保存到其中,如下:
从上面的代码可以看到,Spring寻找合适的bean的要求是一再放宽的 : 非自引用 -> 被 Qualifier 限定符修饰的bean -> 自引用。
autowire-candidate :xml中在注入bean 的时候有该属性。@Bean也有对应的属性。其作用是用来标记当前bean是否会被作为注入的候选bean。默认值 true:表示其他bean可以把当前bean作为属性注入。如果false:表示其他bean选在注入属性 bean时将忽略当前bean。这一点在上面的代码中也有体现。
上面只是将属性保存了起来,并未真正设置到bean中,这里设置到bean中
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List original;
// 如果pvs 是 MutablePropertyValues 类型的封装
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 如果 mpv 中的值类型已经转换完毕,则可以直接设置到BeanWrapper 中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
// 保存原始值,等待类型转换
original = mpvs.getPropertyValueList();
}
else {
// 保存原始值,等待类型转换
original = Arrays.asList(pvs.getPropertyValues());
}
// 获取类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
// 准备进行深拷贝
List deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 遍历属性,将属性转换为对应类的对应属性类型
for (PropertyValue pv : original) {
// 如果已经转换之后直接保存
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
// 进行类型转换
String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
populateBean 在bean创建结束之后,完成了对 bean属性的注入。根据byName、byType 的不同类型注入有不同的解析方式。