Spring版本
5.2.5.RELEASE
参考
源码解读
在《Spring源码解析(八)-创建单例bean》中,创建bean实例的方法doCreateBean
中调用了populateBean
方法来填充bean属性,下面浅析一下具体源码
1. 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.
// 给BeanPostProcessor一个机会在bean填充属性之前改变bean
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
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();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// postProcessProperties:在应用属性到bean之前,对属性做一个post process处理
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
// 过滤出所有需要进行依赖检查的属性编辑器
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 加上filteredPds进行post process处理
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
// 检查依赖
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 属性值设置最终是通过set方法进行,所以这里对要求进行检查的属性进行了检查,检查内容主要有俩项
// 1、是否有set方法
// 2、pvs是否包含filteredPds中的每个元素
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// 应用属性值到bean中
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
核心流程大致可以分为:
- 在填充属性之前,给
InstantiationAwareBeanPostProcessor
一个机会改变属性(关于BeanPostProcessor
,可查阅《Spring源码解析(十四)-BeanPostProcessor》 - 从
BeanDefinition
中获取属性值pvs
,如果注入模式是AUTOWIRE_BY_NAME
或者AUTOWIRE_BY_TYPE
,则分别通过autowireByName
和autowireByType
来获取属性值newPvs
,并覆盖pvs
- 再次给
BeanPostProcessors
机会改变属性,并将改变后的属性值赋值到pvs
中 - 检查依赖,主要是为下一步应用属性到bean中做检查
- 应用属性到bean中
下面浅析较为复杂的子流程
2. InstantiationAwareBeanPostProcessor
该类的源码注释提供了这么一段说明:
/**
* Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
* and a callback after instantiation but before explicit properties are set or
* autowiring occurs.
*/
简单说来,就是这是一个BeanPostProcessor
的子接口,增加了实例化之前的回调功能和实例化之后但设置精确属性或者自动注入发生之前的回调。
所以,在populateBean
中,在设置精确属性和自动注入之前,先判断是否包含InstantiationAwareBeanPostProcessor
:
hasInstantiationAwareBeanPostProcessors()
如果包含,调用postProcessAfterInstantiation
方法:
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
该方法默认返回true
,在populateBean
中,返回false
的情况下会中断填充属性流程
3. AbstractAutowireCapableBeanFactory#autowireByName
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取bean中的非简单属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 获取bean实例
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");
}
}
}
}
3.1 AbstractAutowireCapableBeanFactory#unsatisfiedNonSimpleProperties
首先获取到非简单属性,判断简单属性的核心代码如下:
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
public static boolean isSimpleProperty(Class<?> type) {
Assert.notNull(type, "'type' must not be null");
return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
}
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}
可见,简单属性包含以下数据类型及其对应的数组:
- 基本类型及其包装类型
- 枚举
- 字符串
- Number
- Date
- Temporal
- URI
- URL
- Locale
- Class
3.2 AbstractAutowireCapableBeanFactory#containsBean
对3.1中获取到对简单属性集合进行遍历,通过containsBean
确认已经被解析成bean实例或者已经解析好BeanDefinition
,如果本类判断不出来,在交由parentBeanFactory
递归判断
@Override
public boolean containsBean(String name) {
String beanName = transformedBeanName(name);
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
}
// Not found -> check parent.
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
}
3.2.1 AbstractAutowireCapableBeanFactory#containsSingleton:
@Override
public boolean containsSingleton(String beanName) {
return this.singletonObjects.containsKey(beanName);
}
singletonObjects
用于存放已经实例化的<beanName, bean实例>,具体可看 《Spring源码解析(八)-创建单例bean》
3.2.2 AbstractAutowireCapableBeanFactory#containsBeanDefinition
@Override
public boolean containsBeanDefinition(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return this.beanDefinitionMap.containsKey(beanName);
}
beanDefinitionMap
用于存放已经解析完毕的<beanName,beanDefinition>,具体可看Spring源码解析(六)-解析bean标签
3.3 AbstractAutowireCapableBeanFactory#getBean
如果containsBean
中条件成立,则通过getBean
从缓存获取bean实例,或者递归创建bean实例,之后将bean实例加入pvs
中
3.4 AbstractAutowireCapableBeanFactory#registerDependentBean
通过registerDependentBean
进行依赖注册:
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
逻辑就是往dependentBeanMap
和dependenciesForBeanMap
写入映射关系
4. AbstractAutowireCapableBeanFactory#autowireByType
相对于autowireByName
,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);
// 获取bean中的非简单属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
// 通过propertyName获取持有该属性描述信息的PropertyDescriptor对象
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,直接跳过,Object类型没有意义
if (Object.class != pd.getPropertyType()) {
// 获取set方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
// 对于PriorityOrdered的bean,不允许即刻初始化,因为PriorityOrdered意味着有优先级和顺序的区分
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);
}
}
}
和autowireByName
相同,先获取到非简单属性集合,遍历:
- 获取属性描述符
pd
- 通过属性描述符
pd
和依赖描述符desc
解析出bean实例autowiredArgument
,并且在解析过程中获得autowiredArgument
依赖到bean实例名称集合autowiredBeanNames
- 对
autowiredBeanNames
和beanName
进行依赖关系注册
核心功能点在于resolveDependency
方法
4.1 DefaultListableBeanFactory#resolveDependency
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
// 对Optional的处理,内部依旧调用了doResolveDependency
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 Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 为实际依赖关系目标的延迟解析构建代理
// 默认实现返回 null
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
该方法主要针对各种类型做了对应的处理,这里我们主要关心核心方法doResolveDependency
4.2 DefaultListableBeanFactory#doResolveDependency
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> 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为@Value注解内的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// 解析实际嵌入的值,即将@Value中的值解析成配置的值
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 如果是SPEL表达式,进行SPEL表达式的解析
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
// 如果有必要,进行类型转换
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()));
}
}
// 解析数组、Collection、Map等类型的复合bean
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 获取匹配的bean集合
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 没有匹配的实例,但是Autowire的required为true,抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 匹配集合大于1,获取最合适的bean实例
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
// 没有匹配到合适的bean实例
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
// Autowire的required为true,且不是multipleBean,交由descriptor解析(该方法默认抛出异常)
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.
// 刚好1个
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
// 前面获取到的instanceCandidate已经是一个bean实例了,为何需要再度通过getBean获取bean实例?
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);
}
}
依旧是切分成几个部分来分析:
- 通过
resolveShortcut
来为给定的工厂提供一个快捷解析的方式 - 解析
@Value
注解 - 解析数组、Collection、Map等类型的复合bean
- 查找合适的候选bean集合
matchingBeans
,并从matchingBeans
中确定最合适的bean实例
这里存在一个疑问,经过前面的步骤,
matchingBeans
中存放的已经是实例后的bean,不明白为啥还需要descriptor.resolveCandidate(autowiredBeanName, type, this);
,该方法底层也是调用getBean
,看起来并没有什么意义
4.2.1 DefaultListableBeanFactory#findAutowireCandidates
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 获取到符合类型要求的候选bean名称集合
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 从resolvableDependencies解析出符合requiredType的bean,并解析成对应实例
// 通过resolvableDependencies的put调用及debug可以看到,resolvableDependencies的值一般为:
// BeanFactory.class -> instance
// ResourceLoader.class -> instance
// ApplicationEventPublisher.class -> instance
// ApplicationContext.class -> instance
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
// 符合requiredType类型,或者派生自requiredType
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
// 解析出bean实例
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
// 解析出的bean实例是requiredType的实例
if (requiredType.isInstance(autowiringValue)) {
// 加入结果集
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 从候选者中进行筛选
for (String candidate : candidateNames) {
// 筛选条件
// 1、不能是自我引用
// 2、candidate对应的beanDefinition中是否设置autowire-candidate为true
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty()) {
// 如果依旧没找到,执行降级匹配
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
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;
}
- 筛选出候选bean集合
candidateNames
- 从
resolvableDependencies
筛选出合适的数据加入结果集result
中,resolvableDependencies
比较陌生,从debug来看,预置这四个数据:- BeanFactory.class -> instance
- ResourceLoader.class -> instance
- ApplicationEventPublisher.class -> instance
- ApplicationContext.class -> instance
- 从
candidateNames
筛选出合适的数据加入结果集result
- 如果经过上述步骤,结果集
result
依旧为空,执行降级策略的处理
4.2.2 DefaultListableBeanFactory#determineAutowireCandidate
当matchingBeans
数量大于1时,会进入该方法来决定使用哪个候选值
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// 获取在BeanDefinition中被标记为primary的bean
// <bean id="valueBean" class="com.kungyu.custom.element.ValueBean" primary="true"/>
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 获取优先级最高的bean
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
// 如果上述均不满足,从resolvableDependencies中返回第一个匹配的bean
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
该方法用于从candidates
挑选出最合适的bean名称:
- 如果bean设置了
primary
属性,且值为true
,返回该候选值 - 如果bean设置了优先级,返回优先级最高的候选值
- 如果上述均不满足,从
resolvableDependencies
中获取到匹配名称的第一个候选值
5. AbstractAutowireCapableBeanFactory#checkDependencies
protected void checkDependencies(
String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, @Nullable PropertyValues pvs)
throws UnsatisfiedDependencyException {
int dependencyCheck = mbd.getDependencyCheck();
for (PropertyDescriptor pd : pds) {
// set方法不为空
// pvs属性集合不为空且不包含必须检查的属性
if (pd.getWriteMethod() != null && (pvs == null || !pvs.contains(pd.getName()))) {
// 判断是否是简单属性,如基础数据类型或者string
boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
// 判断是否不满足设定的检查标准
boolean unsatisfied = (dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) ||
(isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
(!isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
// 不满足,抛出异常
if (unsatisfied) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),
"Set this property value or disable dependency checking for this bean.");
}
}
}
}
这一块的逻辑就简单多了,功能就是为了验证要求进行依赖检查的属性pds
拥有对应的set方法,具体看代码注释就可以了。
6. AbstractAutowireCapableBeanFactory#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());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
// 如果属性已经转化完成,直接设置,通过反射调用set方法设置
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<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
// 如果已经转化完成,直接加入deepCopy集合
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
// 如果是Autowire注入
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
// 获取set方法
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
// 原始值构造为持有set方法的DependencyDescriptor
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 使用解析器解析原始值,例如将引用转换为IoC容器中实例化对象引用!
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 判断是否可转化,需要满足条件:
// 1、可写属性
// 2、非内嵌属性或者索引属性(nested or indexed property)
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
// 如果可以转化,进行值转化
// 转化可能是string到int之间的兼容转化
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 {
// 设置值,通过反射调用set方法设置
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
应用属性值到bean中,说白了,就是调用set方法,设置值,大部分代码在于为属性值做解析和转化等功能,而真正做这件事到其实就setPropertyValues
方法:
@Override
public void setPropertyValues(PropertyValues pvs) throws BeansException {
setPropertyValues(pvs, false, false);
}
跟踪调用链,在底层调用方法为BeanWrapperImpl#setValue
:
@Override
public void setValue(final @Nullable Object value) throws Exception {
final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(writeMethod);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
writeMethod.invoke(getWrappedInstance(), value), acc);
}
catch (PrivilegedActionException ex) {
throw ex.getException();
}
}
else {
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value);
}
}
可以看到,原理是使用了反射,执行debug,可以看到writeMethod
就是set方法:
总结
阅读populateBean
源码之前,还以为会相对简单,以为就是获取set方法,再通过set方法进行赋值,结果实际情况远远复杂于原先到设想,只能说,spring真是一个庞大到工程。总而言之,populateBean
核心思想便是对属性值进行填充,属性值可能是基本数据类型之类对,也可能是需要引用其他bean的复杂类型,整体源码围绕这一思想展开。