逻辑说明
populateBean的流程
炒鸡丁的流程
1.执行InstantiationAwareBeanPostProcessor
的postProcessAfterInstantiation
(在设置属性前去修改Bean的状态,也可以控制是否继续填充Bean)
作为一个已婚男人炒菜之前,请示老婆,这很重要。
我:“我炒宫爆鸡丁了,有特殊要求吗?”
老婆大人:“没有要求,炒吧”。
2.注入属性到PropertyValues中(autowireByName/autowireByType)
初步准备食材
准备鸡肉,郫县豆瓣酱,花生米,黄瓜
3.执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues,
对解析完但未设置的属性再进行处理
切菜 鸡肉切丁,黄瓜切小块。
4.对dependency-check属性的支持,默认是不校验
5.将PropertyValues中的属性值设置到BeanWrapper中
下锅,炒熟出锅
autowirebyType的大致逻辑
看了源码总结如下:
- 不处理简单属性,即不处理:Enum,CharSequence,Number,Date,URI,Locale等。(具体可以查看org.springframework.beans.BeanUtils#isSimpleProperty这个方法。)
- 不对Object类型的属性进行自动注入, 没有意义,技术无法实现
- 解析依赖resolveDependency并设置到pvs中
- registerDependentBean 注册当前依赖。
autowiredByType的源码注释
/**
* Abstract method defining "autowire by type" (bean properties by type) behavior.
* 抽象方法 定义 按类型注入
* <p>This is like PicoContainer default, in which there must be exactly one bean
* of the property type in the bean factory. This makes bean factories simple to
* configure for small namespaces, but doesn't work as well as standard Spring
* behavior for bigger applications.
* 类似PicoContainer(非常轻量级的Ioc容器),beanFactory中一个属性类型必须有一个确切对应的bean
* bean工厂很容易配置小的命名空间.
* @param beanName the name of the bean to autowire by type 需要按类型注入的BeanName
* @param mbd the merged bean definition to update through autowiring 合并后的BeanDefinition
* @param bw the BeanWrapper from which we can obtain information about the bean BeanWrapper对象
* @param pvs the PropertyValues to register wired objects with 注册属性的属性值
*/
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//获取需要 注入的 非简单类型
/**
* 简单类型,详见
* @see org.springframework.beans.BeanUtils#isSimpleProperty
*/
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.
// 不对Object类型的属性进行自动注入, 没有意义,技术无法实现
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.
// 假如实现了prioritized post-processor ,在进行类型匹配时,是不允许,eager初始化(热加载)的
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
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);
}
}
}
下回写resolveDependency的逻辑。
一图胜千言
源码注释
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* 填充bean的属性
* @param beanName the name of the bean bean的名称
* @param mbd the bean definition for the bean 合并后的Bean的定义
* @param bw the BeanWrapper with bean instance beanWrapper的对象
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
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.
// 跳过没有属性,null实例
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.
//给任何InstantiationWareBeanPostProcessors在设置属性之前修改bean的状态的机会。
// 例如,这可用于支持属性注入
boolean continueWithPropertyPopulation = true;
//InstantiationWareBeanPostProcessors 可以控制是否继续填充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;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
//根据名称自动注入
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == 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) {
//有InstantiationAwareBeanPostProcessors 对象
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
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);
}
//检查依赖Dependency-check
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
//将属性值设置到Bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}