AbstractAutowireCapableBeanFactory#populateBean()方法
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.
//这里是调用实例化后的后置处理器(还没有进行属性填充)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
/**
* 下面的这段逻辑处理的是@AutoWired,后面在说 这里才是真正开始进行属性填充
*/
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
/**
* 这里调用的又是bean的后置处理器,这里的后置处理器是在bean属性填充过后的bean后置处理器
* 这个后置处理器正在现在用的最多,spring内部定义的InstantiationAwareBeanPostProcessor实现了这个接口,主要处理的是
* @AutoWired的后置处理器,依赖注入的在这里调用的,最重要的是postProcessProperties这个方法
* 所以InstantiationAwareBeanPostProcessor的后置处理器方法postProcessProperties是处理@AutoWired @Resource注解的
* 这个方法后面讲
*/
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//这个方法也可以修改属性值
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//这个方法可以修改属性值
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
//真正开始解析bean的属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
autowireByName()方法
autowireByName() 方法是自动装配的一个实现,它的工作原理是基于 Bean 名称进行匹配和注入。具体地,它会查找当前 Bean 定义中所有需要注入的属性(通常是 setter 方法或者字段),然后尝试在 Spring 容器中查找具有相同名称的 Bean。如果找到了匹配的 Bean,那么它就会被注入到当前 Bean 的相应属性中。
下面是这个方法的一些关键点:
- 查找需要注入的属性:autowireByName() 方法首先会查找当前 Bean 定义中所有需要注入的属性。这通常是通过查找 Bean 类中的 setter 方法或字段来完成的。
- 基于名称匹配:对于每一个需要注入的属性,方法会检查其名称(通常是 setter 方法的名称或字段的名称),然后在 Spring 容器中查找具有相同名称的 Bean。例如,如果有一个名为 setDataSource(DataSource dataSource) 的 setter 方法,那么方法会尝试在容器中查找名为 dataSource 的 Bean。
- 注入匹配的 Bean:如果找到了匹配的 Bean,那么方法会将其注入到当前 Bean 的相应属性中。这通常是通过调用 setter 方法或设置字段的值来完成的。
- 处理依赖关系:注意,自动装配可能会引发依赖关系问题。例如,如果两个 Bean 相互依赖对方,并且都尝试通过自动装配来注入对方,那么这可能会导致循环依赖的问题。Spring 框架会尝试解决这些问题,但并非所有情况都能成功解决。
- 可配置性:虽然 autowireByName() 是自动装配的一种实现,但 Spring 允许通过配置文件或注解来配置自动装配的行为。例如,你可以在 Bean 定义中设置 autowire 属性为 byName 来启用基于名称的自动装配。
需要注意的是,自动装配虽然方便,但也可能引入一些不可预见的问题。因此,在使用自动装配时,建议谨慎考虑其可能带来的影响,并确保对其进行充分的测试。在许多情况下,显式地定义依赖关系(例如,通过构造函数注入或 setter 方法注入)可能是一个更好的选择,因为它提供了更高的可见性和控制力。
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("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");
}
}
}
}
autowireByType()方法
autowireByType() 是 Spring 框架中用于自动装配的另一种方法,它基于 Bean 的类型(by type)进行自动装配。与 autowireByName() 不同,autowireByType() 方法会查找容器中与当前 Bean 属性类型相匹配的 Bean,并将它们注入到相应的属性中。
以下是关于 autowireByType() 方法的一些详细解析:
- 查找需要注入的属性:
与 autowireByName() 类似,autowireByType() 方法首先会识别当前 Bean 定义中需要自动装配的属性。这通常是通过检查 Bean 类中的字段或查找具有特定注解(如 @Autowired)的 setter 方法或构造函数来完成的。 - 基于类型匹配:
对于每一个需要注入的属性,autowireByType() 方法会检查其类型,并在 Spring 容器中查找所有相同或兼容类型的 Bean。如果找到多个相同类型的 Bean,并且没有使用任何额外的限定符(如 @Qualifier 注解或 Bean 名称),Spring 将无法确定要注入哪个 Bean,并可能抛出一个异常。 - 注入匹配的 Bean:
当找到与属性类型匹配的 Bean 时,autowireByType() 方法会将其注入到当前 Bean 的相应属性中。这通常是通过调用 setter 方法或利用反射直接设置字段的值来完成的。 - 处理多个匹配的 Bean:
如果找到多个与属性类型匹配的 Bean,并且没有使用限定符来指定应该注入哪个 Bean,那么 autowireByType() 方法的行为可能会因 Spring 的版本和配置而异。在某些情况下,它可能会抛出一个异常,指示存在多个候选者而无法进行注入。在其他情况下,它可能会尝试使用其他策略(如基于 Bean 名称的优先级)来解决冲突。 - 配置和自定义:
与 autowireByName() 一样,autowireByType() 的行为可以通过 Spring 的配置文件或注解进行配置。例如,可以在 Bean 定义中设置 autowire 属性为 byType 来启用基于类型的自动装配。此外,还可以使用 @Autowired 注解在 Java 类中显式地指定哪些属性应该进行自动装配。 - 注意事项:
虽然 autowireByType() 提供了基于类型的自动装配功能,但它在某些情况下可能会引入问题。特别是当容器中存在多个相同类型的 Bean 时,没有明确指定要注入哪个 Bean 可能会导致不确定性或错误。因此,在使用 autowireByType() 时,建议仔细考虑其潜在的副作用,并确保使用限定符或其他机制来明确指定依赖关系。
总体而言,autowireByType() 是一种方便的自动装配机制,但使用它时需要谨慎,并确保对依赖关系有清晰的了解和控制。在大多数情况下,使用显式的依赖注入(如通过构造函数或 setter 方法注入)可能更为可靠和可维护。
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
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.
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("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);
}
}
}
applyPropertyValues()方法
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());
}
//这个类是 PropertyValues 默认实现类
MutablePropertyValues mpvs = null;
List<PropertyValue> original;//mbd 原始属性集合
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
//如果mbd的属性已解析过,则将其设置到beanWrapper中,并返回
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;//没有则取beanWrapper ,他继承了TypeConverter 相当于默认的类型转换器
}
//bean 属性值解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
//存储解析后的属性值
List<PropertyValue> 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();
//解析属性值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 属性可写 && 不是嵌套(如foo.bar,java中用getFoo().getBar()表示)或者索引(如person.addresses[0])属性
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) {
//标记当前bean 的属性都已解析完成 防止重复解析
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
//最终将解析好的属性值集合设置到beanWrapper中
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}