spring5.0 源码解析 populateBean
populateBean
populateBean 在bean的初始化过程中承担属性填充的任务
-
在设置属性之前,让任何 InstantiationAwareBeanPostProcessors 有机会修改 bean 的状态。
InstantiationAwareBeanPostProcessors 这里体现的有两个方法- Object postProcessBeforeInstantiation 在bean的实例化前调用 可以抑制bean的自动实例化
- boolean postProcessAfterInstantiation 在bean的实例化之后 属性填充之前调用,可以抑制bean的属性填充
- PropertyValues postProcessProperties 在工厂应用给定的属性值之前,对其进行后处理,而不需要任何属性描述符
-
获取 property值
这里取得在BeanDefinition中设置的properrty 值,这些property来自对BeanDefinition的解析
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); -
判断是否为setter函数注入 如果是 使用autowireByName 或者 autowireByType 注入
if (this.autowireMode == AUTOWIRE_AUTODETECT) { // 确定是应用 setter 自动装配还是构造器自动装配。 // 如果它有一个无参数构造函数,它被认为是 setter 自动装配,否则我们将尝试构造函数自动装配。 Constructor<?>[] constructors = getBeanClass().getConstructors(); for (Constructor<?> constructor : constructors) { if (constructor.getParameterCount() == 0) { return AUTOWIRE_BY_TYPE; } } return AUTOWIRE_CONSTRUCTOR; } else { return this.autowireMode; } ```
-
检查 工厂是否持有 InstantiationAwareBeanPostProcessor
-
是否进行依赖检查
-
如果持有 InstantiationAwareBeanPostProcessor 则进行处理 在配置的BeanDefinition的propertyValues被设置到bean实例中之前,我们有机会拦截属性,并更改属性。 自动注入也是在这里实现的
-
如果进行属性检查 过滤出需要依赖检查的属性 , 查依赖关系,保证依赖项已初始化
-
Property 的属性填充
/**
* 这一段代码是Spring用来提供给程序员扩展使用的, 如果我们不希望一个bean参与到属性注入, 自动装配的流
* 程中, 那么就可以创建一个InstantiationAwareBeanPostProcessor后置处理器的实现类, 重写其
* postProcessAfterInstantiation方法, 如果该方法返回false, 那么continueWithPropertyPopulation
* 这个变量会被置为false, 而这个变量被置为false, 在下面我们可以看到直接就return了, 从而Spring就不
* 会对属性进行注入
*/
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// 跳过空实例的属性填充阶段.
return;
}
}
// 在设置属性之前,让任何 InstantiationAwareBeanPostProcessors 有机会修改 bean 的状态。例如,这可用于支持字段注入样式。
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 备案 实例化后的处理 同样可以抑制属性注入
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
// 这里取得在BeanDefinition中设置的properrty 值,这些property来自对BeanDefinition的解析
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 开始进行依赖注入过程,先处理 autoWire 的注入
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根据名称自动注入.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根据类型自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//返回工厂是否持有 InstantiationAwareBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否进行依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.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) {
// Property 的属性填充
applyPropertyValues(beanName, mbd, bw, pvs);
}
autowireByName
从下面可以看出 setter 方法通过名称查找 ,如果该名称的bean不错在则报错啦
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取可set的属性,且这个属性不是简单的属性,比如基本类型、包装类这些
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 是否存在这个bean 名称
if (containsBean(propertyName)) {
// 获取 bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 注册依赖关系 主要为了在该bean 销毁之前 先销毁依赖的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
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);
//获取可set的属性,且这个属性不是简单的属性,比如基本类型、包装类这些
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);
// 是否立即初始化
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);
}
}
}
resolveDependency
autowireByType 通过 resolveDependency 方法获取对应 bean
- Optional:JDK8 提供了 API。主要是将依赖设置非强制依赖,即 descriptor.required=false。
- 延迟依赖注入支持:ObjectFactory、ObjectProvider、javax.inject.Provider 没有本质的区别。
- 另一种延迟注入的支持 - @Lazy 属性。
- 根据类型查找依赖 - doResolveDependency。
前四种场景(Optional,延迟注入 ObjectProvider + @Lazy)
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// ParameterNameDiscovery 用于解析方法参数名称
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 1. Optional<T> JDK8 提供了 API。主要是将依赖设置非强制依赖,即 descriptor.required=false。
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 2. ObjectFactory<T>、 延迟依赖注入支持:ObjectFactory、ObjectProvider、javax.inject.Provider 没有本质的区别。
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// ObjectProvider<T>
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 4. @Lazy
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
// 5. 正常情况
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
doResolveDependency
重点看一下单个依赖的查询
如何有多个依赖怎么处理?其实 Spring 有一套通用的流程,先按 @Primary 查找,再按 @Priority,最后按方法名称或字段名称查找,直到只有一个 bean 为止
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 1. 快速查找,根据名称查找。AutowiredAnnotationBeanPostProcessor用到
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 2. 注入指定值,QualifierAnnotationAutowireCandidateResolver解析@Value会用到
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// 2.1 占位符解析
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 2.2 Spring EL 表达式
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
// 2.3 类型转换
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 3. 集合依赖,如 Array、List、Set、Map。内部查找依赖也是使用findAutowireCandidates
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 4. 单个依赖查询
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
// 4.1 没有查找到依赖,判断descriptor.require
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 4.2 有多个,如何过滤
if (matchingBeans.size() > 1) {
// 4.2.1 @Primary -> @Priority -> 方法名称或字段名称匹配
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
// 4.2.2 根据是否必须,抛出异常。注意这里如果是集合处理,则返回null
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), 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;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 4.3 到了这,说明有且仅有命中一个
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
InstantiationAwareBeanPostProcessor
CommonAnnotationBeanPostProcessor
在属性注入环节 它主要作用是 对@Resource注解的处理
/**
* 获取所有待注入的元素:
* 这些元素是在 postProcessMergedBeanDefinition 阶段被收集起来的
*/
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;
AutowiredAnnotationBeanPostProcessor
** 继承InstantiationAwareBeanPostProcessorAdapter、实现 MergedBeanDefinitionPostProcessor 是为了根据后处理器的调用时机来完成一些功能。
** 实现 PriorityOrdered 接口是为了标注自身优先注入。
** 实现 BeanFactoryAware 是为了拿到 BeanFactory。
postProcessProperties & postProcessPropertyValues
在这两个方法中完成了@Autowired、@Inject、 @Value 注解的解析。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
/**
* 获取所有待注入的元素:
* 这些元素是在 postProcessMergedBeanDefinition 阶段被收集起来的
*/
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
/**
* 进行元素注入
*/
try {
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;
}
他们两个在这一步的不同之处 在于一个处理@Resource注解 ,一个处理 @Autowired 的注解
applyPropertyValues
方法的主要逻辑是遍历 bd.propertyValues 中的 PropertyValue 属性,根据引用类型提取出对象实例,再将这个对象实例转换成可以直接注入的实例。
- 解析对象:valueResolver.resolveValueIfNecessary(pv, originalValue) 将 pv.value 解析成实例对象。
- 类型转换:convertForProperty(resolvedValue, propertyName, bw, converter) 将 resolvedValue 转换成可直接进行类型注入的类型。
- 依赖注入: bw.setPropertyValues(mpvs) 将解析后的属性注入到 bw 实例中。Spring 属性注入(一)JavaBean 内省机制在 BeanWrapper 中的应用。
- 结果缓存:Spring 会将 valueResolver 和 converter 解析后的最终对象缓存到 pv 中,提高效率。如果全部 pv 都不需要重新解析,则设置 mpvs.converted=true。