千家信息网

Spring在单值注入时如何按类型查找匹配的Bean

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,Spring在单值注入时如何按类型查找匹配的Bean,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。引言我经常写如下代码:@Autowir
千家信息网最后更新 2026年11月01日Spring在单值注入时如何按类型查找匹配的Bean

Spring在单值注入时如何按类型查找匹配的Bean,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

引言

我经常写如下代码:

@Autowired private AService aservice;

不知你是否也好奇,Spring是如何找到AService类型的Bean的呢?,我们就聊聊这个->单值注入时如何按类型查找匹配的Bean.

单值注入时如何按类型查找匹配的Bean

很简单,核心就3步。

1.找到所有与类型匹配的bean,如果只有一个直接返回。

Spring在DefaultListableBeanFactory.findAutowireCandidates方法中实现。 其部分源码如下:

String[] candidateNames =        BeanFactoryUtils .beanNamesForTypeIncludingAncestors        ( this, requiredType, true, descriptor.isEager());

这个beanNamesForTypeIncludingAncestors的作用就是,获取requiredType(AService)类型所有匹配的beanName(包含先祖BeanFactory)。

beanNamesForTypeIncludingAncestors内部是如果实现的呢?我概括了下简要逻辑如下:

  • 遍历所有的BeanDefinition,获得所有的BeanName.

  • 针对所有的BeanName,先尝试获取单例进行匹配,若未匹配上再以Bean Definition进行匹配。

  • 匹配时,如果Bean是FactoryBean,先尝试FactoryBean生产的实际Bean进行匹配,若未匹配上再以FactoryBean 进行匹配。

2.多个Bean匹配时,有首选,返回首选的bean。

DefaultListableBeanFactory.determinePrimaryCandidate实现了筛选首选Bean的逻辑, 其中的核心方法是isPrimary,该方法是判断当前Bean是否是首选Bean的。源码如下:

protected boolean isPrimary(String beanName, Object beanInstance) { if (containsBeanDefinition(beanName)) {         return getMergedLocalBeanDefinition(beanName).isPrimary();} BeanFactory parent = getParentBeanFactory();         return (parent instanceof DefaultListableBeanFactory && ((DefaultListableBeanFactory) parent).isPrimary(beanName,beanInstance)); }

getMergedLocalBeanDefinition(beanName).isPrimary()方法,对应AbstractBeanDefinition的primary属性,该属性被赋值的地方是在AnnotatedBeanDefinitionReader.doRegisterBean方法中。有如下逻辑。

//省略甚多代码...... for (Class qualifier : qualifiers) {if (Primary.class == qualifier) {   abd.setPrimary(true); } //省略很多代码....

看到这,我们可以得出一个结论:

被@Primary注解的bean,单值注入时会作为首选。

3.没有首选,按优先级选择,返回优选的Bean。

Spring是如何确定Bean的优先级的呢?

在DefaultListableBeanFactory.determineHighestPriorityCandidate中,实现按优先级选择Bean 其中,获取Bean的优先级的逻辑在getPriority方法中,如下:

protected Integer getPriority(Object beanInstance) { Comparator comparator = getDependencyComparator(); if (comparator instanceof OrderComparator) {         return ((OrderComparator) comparator).getPriority(beanInstance);}         return null; }

查看OrderComparator的实现类AnnotationAwareOrderComparator中的源码发现, 获取优先级的逻辑实际在在OrderUtils.getPriority 中

public static Integer getPriority(Class type) { if (priorityAnnotationType == null) {   return null;} Object cached = priorityCache.get(type); if (cached != null) {        return (cached instanceof Integer ? (Integer) cached : null);}Annotation priority = AnnotationUtils.findAnnotation(type, priorityAnnotationType);Integer result = null; if (priority != null) {         result = (Integer) AnnotationUtils.getValue(priority);} priorityCache.put(type, (result != null ? result : NOT_ANNOTATED)); return result;}

在OrderUtils 向上查找发现 priorityAnnotationType的值为:

priorityAnnotationType = (Class) ClassUtils.forName("javax.annotation.Priority", OrderUtils.class.getClassLoader());

被@Priority注解的类,其值越小,在单值注入时,越优先选择。

Spring的源码非常多,仅有这3步当然是不行的,我准备了流程图,梳理了Spring单值注入时查找匹配Bean的流程。

单值注入时如何按类型查找匹配的Bean的流程图

看完上述内容,你们掌握Spring在单值注入时如何按类型查找匹配的Bean的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

类型 方法 优先级 逻辑 源码 代码 流程 选择 内容 实际 属性 更多 核心 注解 流程图 问题 尝试 不行 好奇 束手无策 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技名片 天津市摩尔互联网科技 哈尔滨大商圈互联网科技有限公司 山东特亿宝互联网科技有限公司 互联网为科技 期待互联网科技 万达互联网科技 成都仁贤领冠互联网科技有限公司 互联网和高科技公司 欧洲十大科技互联网公司 阿里互联网科技公司 上海宁丞科技互联网 深圳市罗太互联网科技有限公司 特约风豹互联网科技为什么扣费 上海钢联属于互联网科技股吗 江苏苏星互联网科技有限公司 电子商务与互联网科技的关系 从那以后互联网科技有限公司 风投北京互联网科技 科技互联网专业工作会议发言稿 花魁咖啡 科技赋能下的互联网金融 睿民互联网科技 撒么互联网科技公司 西藏七维空间互联网科技有限公司 恒银科技与互联网金融 互联网科技项目计划书材料类 智腾互联网科技有限公司 企晟互联网信息科技有限公司 小牛互联网科技有限公司地址
0