@Autowired和@Resource默认字段注入流程源码分析
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了@Autowired和@Resource默认字段注入流程源码分析,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3948字,纯文字阅读大概需要6分钟。
内容图文
![@Autowired和@Resource默认字段注入流程源码分析](/upload/InfoBanner/zyjiaocheng/602/3af5d7c7a7d0499284230c859959a1ce.jpg)
1 结论
1)@Autowired 注入流程
- 根据注入字段类型注入bean,若仅有一个bean则返回;
- 若有多个该类型的bean,则注入规则如下:
1. 根据@Primary注解确定 2. 根据@Priority确定 3. 根据字段名称确定
2)@Resource 注入流程
- 不指定name的情况下,注入流程同@Autowired;
- 指定了beanName的情况下,则直接根据beanName注入依赖。
2 源码分析
2.1 @Autowired
核心代码(org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency):
// 注入的依赖字段类型 Class<?> type = descriptor.getDependencyType(); 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())); } } Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 找到依赖类型的所有bean 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; // 如果相同类型的依赖bean有多个 if (matchingBeans.size() > 1) { /* 1. 根据@Primary注解确定 2. 根据@Priority确定 3. 根据字段名称确定 */ 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); }
2.2 @Resource
@Resource注解相较@Autowired可以指定beanName,若未设置javax.annotation.Resource#name,则默认注入依赖bean的流程与@Autowired一致。
核心代码(org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#autowireResource):
String name = element.name; if (factory instanceof AutowireCapableBeanFactory) { AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory; DependencyDescriptor descriptor = element.getDependencyDescriptor(); if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) { autowiredBeanNames = new LinkedHashSet<>(); resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null); if (resource == null) { throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object"); } } // 指定了bean名称 else { // 根据依赖的名字获取依赖bean对象 resource = beanFactory.resolveBeanByName(name, descriptor); autowiredBeanNames = Collections.singleton(name); } } else { resource = factory.getBean(name, element.lookupType); autowiredBeanNames = Collections.singleton(name); } if (factory instanceof ConfigurableBeanFactory) { ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory; for (String autowiredBeanName : autowiredBeanNames) { // 设置bean与其注入bean之间的依赖关系 if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) { beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName); } } } return resource;
内容总结
以上是互联网集市为您收集整理的@Autowired和@Resource默认字段注入流程源码分析全部内容,希望文章能够帮你解决@Autowired和@Resource默认字段注入流程源码分析所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。