阅读本文需要有一定的基础,并且要跟着调用链走,不然会很容易懵圈。
Spring Framework Version:5.3.x
Gradle Version:7.5.1
内容比较干,要有点耐心哈~
/**
*
* 属性填充
* param beanName bean名称
* param mbd bean定义
* param bw bean包装器
*
*/
@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.
return;
}
}
//在属性注入之前回调instantiationAware后置处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
//byName、byType注入
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;
}
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) {
//对属性进行后置处理,处理使用@Resource、@Autowired注解这种注入方式(最深层也是使用反射对Field进行set)
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) {
//真正进行set注入、byName和byType注入的地方,前面的byName和byType只是先找到bean,还没有真正的注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
至此,属性填充的流程就讲解完了,接下来我们一一来看他们的具体实现
讲解顺序
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//根据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;
}
/**
* 容器第一次启动在AbstractAutowireCapableBeanFactory类中的applyMergedBeanDefinitionPostProcessors方法中调用
* 查询需要进行依赖注入的元数据,这块主要针对@Resource注解
*/
private InjectionMetadata findResourceMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
//使用类名作为缓存键,以便与自定义调用程序向后兼容。
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//这里使用了一个双检锁来判断元数据是否需要刷新(第一次启动容器都需要去构建元数据,并放入缓存中)
// 这一块的数据一般由applyMergedBeanDefinitionPostProcessors处理,属性填充时缓存直接从缓存中获取即可
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//主要构建@Resource注解元数据,如果属性上没有@Resource注解,那么也会构建元数据对象,但是注入元素为0
metadata = buildResourceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
该方法主要构建Resource元数据,流程如下:
private InjectionMetadata buildResourceMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
//存储带有对应注解的属性或方法,用于构建InjectionMetadata
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
//用于存储带有对应注解的属性或方法,最后添加到elements中
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//检查属性上是否有WegServiceRef、EJB、Resource等注解,如果有,检查是否是静态属性,是的话抛异常,否则添加到currElements中
ReflectionUtils.doWithLocalFields(targetClass, field -> {
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
}
currElements.add(new WebServiceRefElement(field, field, null));
}
else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static fields");
}
currElements.add(new EjbRefElement(field, field, null));
}
else if (field.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static fields");
}
if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
});
//检查方法上是否有WegServiceRef、EJB、Resource等注解,如果有,检查是否是静态方法,是的话抛异常,否则添加到currElements中
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
}
else if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new EjbRefElement(method, bridgedMethod, pd));
}
else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new ResourceElement(method, bridgedMethod, pd));
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
//创建元数据并返回
return InjectionMetadata.forElements(elements, clazz);
}
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
//进行注入,inject是个方法重载
element.inject(target, beanName, pvs);
}
}
}
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);
//通过反射invoke method,注意getResourceToInject方法,
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
这块的源码就不带着去看了,感兴趣的同学可自行debug调试,我大概说一下核心流程
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//查找自动注入元数据
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;
}
/**
* 容器第一次启动在AbstractAutowireCapableBeanFactory类中的applyMergedBeanDefinitionPostProcessors方法中调用
* 查询需要进行依赖注入的元数据,这块主要针对@Autowired注解
*/
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// 使用类名作为缓存键,以便与自定义调用程序向后兼容。
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
//先从缓存中获取,如果为null,那么则需要构建InjectionMetadata
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//这里使用了一个双检锁来判断元数据是否需要刷新(第一次启动容器都需要去构建元数据,并放入缓存中)
// 这一块的数据一般由applyMergedBeanDefinitionPostProcessors处理,属性填充时缓存直接从缓存中获取即可
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 = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
该方法主要构建@Autowired注解元数据,流程如下:
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
//存储带有对应注解的属性或方法,用于构建InjectionMetadata
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
//用于存储带有对应注解的属性或方法,最后添加到elements中
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//查询属性上是否有@Autowired注解,如果有并且不是静态属性,那么添加到currElements中
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
//判断是否是静态属性
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
//查询方法上是否有@Autowired注解,如果有 并且不是静态方法,那么添加到currElements中
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
//创建元数据并返回
return InjectionMetadata.forElements(elements, clazz);
}
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
//看这里
element.inject(target, beanName, pvs);
}
}
}
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
//检查是否有缓存
if (this.cached) {
try {
//解析缓存中的参数
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
//解析字段值
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
//给属性做一系列检查,满足条件就设置可访问,否则不做任何设置
ReflectionUtils.makeAccessible(field);
//使用反射动态给字段填充属性
field.se
t(bean, value);
}
}
这块的源码就不带着去看了,嵌套的层级较深,我简单讲解下大概做了哪些事(核心功能),如果感兴趣的同学在调试的时候可以自行查看
处理@Value注解
根据类型查询候选者
三种匹配候选者方式
解析候选者(getBean)
这块比较简单,就几个步骤,因为这里只是把值添加到PropertyValues中,后续需要进行注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//检查bean是否包含属性
if (containsBean(propertyName)) {
//getBean
Object bean = getBean(propertyName);
//添加到PropertyValues中,用于后续的反射注入
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");
}
}
}
}
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 an 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);
//如果参数不为null,则添加到PropertyValues中
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName); //注册依赖bean
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
//清空bean名称
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
@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()) {
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 {
//如果没有,最终会走到这里
//如果有必要,使用延迟解析代理
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//真正解析依赖的地方
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
设置当前的注入点
解析bean的快捷方式
处理@Value注解
根据类型查询候选者
三种匹配候选者方式
解析候选者(getBean)
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//设置当前的注入点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
//解析bean的快捷方式
Object shortcut = descriptor.resolveShortcut(this);
//返回null, 因为在子类AbstractAutowireCapableBeanFactory中没有实现
if (shortcut != null) {
return shortcut;
}
//获取依赖类型
Class<?> type = descriptor.getDependencyType();
//获取@Value的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
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()));
}
}
//解析多个bean
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//查找自动候选者,其实就是查找候选者类型
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
//存在多个类型相同的依赖时,选定一个依赖
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
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();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
//解析候选者,也就是getBean
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);
}
}
看完这一块,比较细心的同学就会发现,这里查找候选者的逻辑是和@Autowired是一样的,方法都是复用的,有的同学可能就会有疑问,怎么我写的方法名和这里的不一样。。。那是因为在resolveFieldValue方法内部调用了
set注入、byType、byName都是在这里面进行注入,前面的byName、byType只是查找候选者,在这里才是真正的注入
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;
//校验pvs是否是MutablePropertyValues类型的
if (pvs instanceof MutablePropertyValues) {
//将pvs转换为MutablePropertyValues类型
mpvs = (MutablePropertyValues) pvs;
//如果只包含了转换后的值,返回true, 如果有些值还需要转换,返回false
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<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();
//是否是自动解析的
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);
}
//解析参数值(getBean)
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 {
//如果是使用的是set注入,或者byType、byName注入,这里就是真正的注入入口点
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
@Override
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
throws BeansException {
List<PropertyAccessException> propertyAccessExceptions = null;
//获取属性集合
List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
if (ignoreUnknown) {
this.suppressNotWritablePropertyException = true;
}
try {
for (PropertyValue pv : propertyValues) {
// setPropertyValue may throw any BeansException, which won't be caught
// here, if there is a critical failure such as no matching field.
// We can attempt to deal only with less serious exceptions.
try {
//注入属性值,主要看这里,一直往里走
setPropertyValue(pv);
}
catch (NotWritablePropertyException ex) {
if (!ignoreUnknown) {
throw ex;
}
// Otherwise, just ignore it and continue...
}
catch (NullValueInNestedPathException ex) {
if (!ignoreInvalid) {
throw ex;
}
// Otherwise, just ignore it and continue...
}
catch (PropertyAccessException ex) {
if (propertyAccessExceptions == null) {
propertyAccessExceptions = new ArrayList<>();
}
propertyAccessExceptions.add(ex);
}
}
}
finally {
if (ignoreUnknown) {
this.suppressNotWritablePropertyException = false;
}
}
// If we encountered individual exceptions, throw the composite exception.
if (propertyAccessExceptions != null) {
PropertyAccessException[] paeArray = propertyAccessExceptions.toArray(new PropertyAccessException[0]);
throw new PropertyBatchUpdateException(paeArray);
}
}
@Override
public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {
AbstractNestablePropertyAccessor nestedPa;
try {
//获取属性路径的属性访问器
nestedPa = getPropertyAccessorForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
}
//获取属性令牌
PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
//设置属性值
nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));
}
protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
if (tokens.keys != null) {
//处理集合属性
processKeyedProperty(tokens, pv);
}
else {
//处理本地属性,主要看这里
processLocalProperty(tokens, pv);
}
}
private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {
//获取属性处理器
PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
//判断属性处理器是否为null or 属性不可写
if (ph == null || !ph.isWritable()) {
//是否是Optional
if (pv.isOptional()) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring optional value for property '" + tokens.actualName +
"' - property not found on bean class [" + getRootClass().getName() + "]");
}
return;
}
if (this.suppressNotWritablePropertyException) {
// Optimization for common ignoreUnknown=true scenario since the
// exception would be caught and swallowed higher up anyway...
return;
}
throw createNotWritablePropertyException(tokens.canonicalName);
}
Object oldValue = null;
try {
Object originalValue = pv.getValue();
Object valueToApply = originalValue;
//是否需要进行转换
if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
//在前面转换过了不需要重复转换
if (pv.isConverted()) {
valueToApply = pv.getConvertedValue();
}
else {
if (isExtractOldValueForEditor() && ph.isReadable()) {
try {
oldValue = ph.getValue();
}
catch (Exception ex) {
if (ex instanceof PrivilegedActionException) {
ex = ((PrivilegedActionException) ex).getException();
}
if (logger.isDebugEnabled()) {
logger.debug("Could not read previous value of property '" +
this.nestedPath + tokens.canonicalName + "'", ex);
}
}
}
//属性转换
valueToApply = convertForProperty(
tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());
}
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
}
//设置属性值
ph.setValue(valueToApply);
}
catch (TypeMismatchException ex) {
throw ex;
}
catch (InvocationTargetException ex) {
PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
if (ex.getTargetException() instanceof ClassCastException) {
throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
}
else {
Throwable cause = ex.getTargetException();
if (cause instanceof UndeclaredThrowableException) {
// May happen e.g. with Groovy-generated methods
cause = cause.getCause();
}
throw new MethodInvocationException(propertyChangeEvent, cause);
}
}
catch (Exception ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(
getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
throw new MethodInvocationException(pce, ex);
}
}
setValue在AbstractNestablePropertyAccessor类中是一个抽象方法,由子类实现,子类有两个,分别是BeanPropertyHandler(BeanWrapperImpl的内部类)、FieldPropertyHandler(DirectFieldAccessor类的内部类),如果不是集合类属性,那么默认使用BeanPropertyHandler处理
@Override
public void setValue(@Nullable Object value) throws Exception {
//获取set方法
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);
}
}
至此,四种属性注入方式就讲解完毕了,有同学可能会有疑惑,不是5种吗。。。其实不是,因为byName、byType属于一类(自动装配)
@Resource方式注入:先根据beanName去查找候选者,如果找到了直接返回进行注入,如果没找到,那么根据类型去解析beanName,最后在getBean拿到候选者进行注入
@Autowired注入:根据类型去查找候选者,如果找到了就进行注入,找不到就进行回退策略,然后根据@Qualifier注解去匹配,匹配不上直接报错,如果该类型的bean有多个,那么就先根据@Qualifier注解去匹配,如果没用上@Qualifier注解,那么就都加入到候选者中,然后就从多个候选者中选出一个候选者进行注入,大致流程是这样的:先根据@Primary匹配,匹配不上,再根据优先级进行匹配,如果还匹配不上,那么进行回退策略,根据beanName进行匹配,匹配上了就返回,还匹配不上,直接抛异常
set注入:set注入属于显式的注入值了,所以不会存在找不到
自动装配(byName、byType):byName的话,根据名称自动装配,找不到无事发生,不会报错,但是没有装配成功,如果进行调用,那么会报空指针异常,byType一样,根据类型匹配,如果该类型的bean有多个,那么进行回退匹配,看看有没有@Qualifier注解,如果有,那么进行名称匹配,否则报错