Spring-@Resource和@Autowired的分析
从源码分析了@Resource和@Autowired的依赖创建流程和这两个注解的的异同
紧接上篇文章Spring-Bean的字段填充阶段相关处理器
@Resource
CommonAnnotationBeanPostProcessor#autowireResource部分核心源码
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
// field依赖会构建成LookupDependencyDescriptor,required只能为true
DependencyDescriptor descriptor = element.getDependencyDescriptor();
// byType
// 当不设置@Resource.name字段值,以字段名作为beanName的Bean不在容器中
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
autowiredBeanNames = new LinkedHashSet<>();
// 解析依赖bean
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
} else { // byName
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
}
@Autowired
AutowiredFieldElement#resolveFieldValue部分核心源码
// 此时required可由我们定义,表示这个bean不再是必须存在的
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
Object value;
try {
// 解析依赖bean,只有byType
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
公共的解析源码
AutowireCapableBeanFactory#resolveDependency
主要流程:
- 判断注入点是否标注了
@Lazy
,如有,则返回懒加载代理对象;- 若标注了
@Value
,解析其占位符表达式并进行类型转换;- 判断依赖类型,若是集合类型(如 List、Map、Stream 、数组等),则调用
resolveMultipleBeans
获取所有候选- 若为单个 Bean 类型,则根据类型查找候选 Bean,结合
@Qualifier
、@Primary
、@Priority
等注解进行筛选;- 若无匹配 Bean,是否抛出异常由
required
属性决定。
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
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 {
// 判断是否有@Lazy注解。使用了@Lazy则在这里直接创建了代理对象并返回
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 开始获取依赖bean
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
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注解
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) { // 多bean解析出来了则直接返回
return multipleBeans;
}
// 将这个type所有的可能bean都解析出来
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) { // 没找到
if (isRequired(descriptor)) {
// 如过required为true,会直接跑异常
// 只有@Autowired才可设置required为false
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
// ====== 走到这表示这个bean是单个的,需要再根据其他注解来返回一个优先级最高的bean ======
// 最终的依赖beanName
String autowiredBeanName;
// 最终的依赖bean实例
Object instanceCandidate;
if (matchingBeans.size() > 1) { // 存在多个候选bean
// 会先根据@Primary注解筛选,否则根据@Priority筛选出优先级最高的bean
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) { // 异常处理,根据required选择是否跑异常
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else { // 只有1个候选bean
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 = 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);
}
}
DefaultListableBeanFactory#resolveMultipleBeans
支持注入类型为 Collection<T>
、Map<String, T>
、T[]
和 Stream<T>
的多 Bean 依赖。该方法会查找所有匹配的候选 Bean,按类型筛选、处理限定符(如 @Qualifier
),并封装成目标集合类型返回。
/**
处理依赖bean的type是一个容器的情况。可能为 数组、集合、Map甚至Stream
*/
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
Class<?> type = descriptor.getDependencyType();
if (descriptor instanceof StreamDependencyDescriptor) { // type = Stream
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream<Object> stream = matchingBeans.keySet().stream()
.map(name -> descriptor.resolveCandidate(name, type, this))
.filter(bean -> !(bean instanceof NullBean));
if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
stream = stream.sorted(adaptOrderComparator(matchingBeans));
}
return stream;
}
else if (type.isArray()) { // type = 数组
Class<?> componentType = type.getComponentType();
ResolvableType resolvableType = descriptor.getResolvableType();
Class<?> resolvedArrayType = resolvableType.resolve(type);
if (resolvedArrayType != type) {
componentType = resolvableType.getComponentType().resolve();
}
if (componentType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
if (result instanceof Object[]) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
Arrays.sort((Object[]) result, comparator);
}
}
return result;
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { // type = 集合
// 解析出这个bean的范型type
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
// 找出匹配范型type的候选bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (result instanceof List) {
if (((List<?>) result).size() > 1) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
return result;
}
else if (Map.class == type) { // type = Map
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
if (String.class != keyType) {
return null;
}
// 解析出Map中value的type
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
// 对value type进行bean搜索,返回
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
return null;
}
}
DefaultListableBeanFactory#findAutowireCandidates
DefaultListableBeanFactory#findAutowireCandidates
用于查找参数中 beanName(如 Bean A)所依赖的、类型为 requiredType
的所有候选 Bean(如 Bean B)。返回结果为一个 Map<String, Object>
,其中 key
是候选 Bean 的名称,value
是对应的实例。
方法内部会先在 BeanFactory 中找出所有类型匹配 requiredType
的 Bean 名称,然后根据限定注解(如 @Qualifier
)等条件进行筛选。筛选通过的候选 Bean 会被递归创建并作为依赖返回。
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 找出这个type所有的beanName
// 内部就是遍历BeanFactory中所有的BeanDefinition,依次进行type匹配判断,在收集结果并缓存
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 一些特殊bean的处理,比如ApplicationContext之类的bean
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 依次判断每个候选beanName,看其是否有资格成为真正的目标bean
for (String candidate : candidateNames) {
// 非自引用,isAutowireCandidate最终会调用到QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate方法,根据@Qualifier注解来判断是否是目标bean
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 目标bean,会使用BeanFactory来获取这个bean。实现递归创建bean
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty()) { // 上面的流程没找到,则进行fallback放宽条件继续找
boolean multiple = indicatesMultipleBeans(requiredType);
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) { // 继续放宽条件
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解析(比如Stream,数组,集合,Map)
- 都支持
@Lazy
,@Qualifier
,@Value
等注解 - 都支持字段、方法参数
不同点
- @Autowired可以设置required为false,即不强制需要这个bean。而@Resource则必须要对应的bean存在
- @Resource由javax提供,是集byName和byType为一体的注解。框架无关,属于 Java 官方对 IOC 容器的通用约定。在Spring中,当没设置@Resource的name,并且由框架解析出来的name(字段名or去掉set的方法名)不在容器中才会使用byType
- @Autowired本身只能byType,搭配@Qualifier才可实现byName