一、问题复现和详细异常

今天一个同事在开发时给一个类(AServiceImpl)加了@AllArgsConstructor,希望通过private final 的方式将XxClassXxxClass注入到当前类:

@Service
@AllArgsConstructor
public class AServiceImpl implements AService{private final XxClass xxClass;private final XxxClass xxxClass;@Value("${my.value:myValue}")private String value;.....
}

运行时报错如下:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1777) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1333) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1287) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1206) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:571) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.2.jar:5.3.2]at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:923) ~[spring-context-5.3.2.jar:5.3.2]at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.2.jar:5.3.2]at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.1.jar:2.4.1]at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) [spring-boot-2.4.1.jar:2.4.1]at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.4.1.jar:2.4.1]at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.1.jar:2.4.1]at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.1.jar:2.4.1]at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) [spring-boot-2.4.1.jar:2.4.1]at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) [spring-boot-2.4.1.jar:2.4.1]at com.saint.DemoTestApplication.main(DemoTestApplication.java:10) [classes/:na]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1777)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1333)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1287)at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)... 28 common frames omitted

二、原因分析

从报错提示可以看出是没有找到NoSuchBeanDefinition;根本原因是因为springioc容器加载bean默认使用无参构造进行初始化,就示例而言,需要用到只有一个入参的构造函数(AClassImpl(XsClass));

由于此处使用的是@AllArgsConstructor注解,所以对AClassImpl而言,只有一个构造函数(AClassImpl(XxClass, XxxClass, String)),而构造函数的第三个参数是用@Value注入导入的一个属性值,其并不会存在于Spring容器,所以报错。

源码分析

从报错信息找到出错的入口:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)

这里可以看到获取到的AServiceImpl的构造函数中有三个入参,最后一个入参是String类型;

然后顺着报错日志的执行链路,找到

这里ConstructorResolver#resolveAutowiredArgument()方法会判断 用于解析指定参数的模板方法 是否支持被自动注入(autowired);非Class类型均不行。

抛出异常的源码位置如下:

因为采用构造函数注入属性的方式,属性是必须要存在于Spring容器的,所以这里检查参数必须性时会校验不通过(即不会提前return),进而报错;

三、解决方案

一般可以给AServiceImpl提供一个默认的构造方法来解决,但此处需要注入XxClassXxxClass,所以仅需生成一个只包含XxClassXxxClass两个参数的构造方法即可。
因此,我们选择使用@RequiredArgsConstructor注解来替换@AllArgsConstructor注解;

@RequiredArgsConstructor 和 @AllArgsConstructor的区别?

  • @RequiredArgsConstructor会将类的每一个final字段或者non-null字段生成一个构造方法
  • @AllArgsConstructor 生成一个包含所有字段的构造方法;
  • @NoArgsConstructor 生成无参的构造方法;

使用@RequiredArgsConstructor可以代替@Autowrited注解;而@RequiredArgsConstructor是根据构造器注入的,所以会有循坏依赖的问题。

@RequiredArgsConstructor循环依赖问题解决措施

有三种方式可以解决:

  1. 改为使用@Autowired注解做属性方法注入Bean;
    不过,Spring 从 4.0 开始, 就不推荐使用属性注入模式了,原因在于它可以让我们忽略掉一些代码可能变坏的隐患。
  2. 使用@RequiredArgsConstructor(onConstructor =@_(@Autowired) ),这样默认都是通过@Autowired注入Bean的;
  3. 使用@RequiredArgsConstructor(onConstructor_={@Lazy} ),做懒加载处理。

No qualifying bean of type ‘java.lang.String‘ available: expected at least 1 bean which qualifies相关推荐

  1. No qualifying bean of type ‘java.lang.String‘ available expected

    错误提示: java.lang.IllegalStateException: Failed to load ApplicationContextat org.springframework.test. ...

  2. Consider defining a bean of type ‘java.lang.String‘ in your configuration

    Consider defining a bean of type 'java.lang.String' in your configuration 总结了网上的几种解决方案: 1.多余的@autowi ...

  3. springboot启动报错Parameter 0 of method a in com.* required a bean of type 'java.lang.String' that could

    springboot服务启动报错,报错信息如下 *************************** APPLICATION FAILED TO START ******************** ...

  4. 解决 No converter found capable of converting from type [java.lang.String] to type ... 的问题

    目录 问题 分析问题 解决问题 问题 今天在项目启动类SuperJsonManagerApplication中,加上这行代码@MapperScan("com.**.mapper") ...

  5. Failed to convert property value of type java.lang.String to required type java.lang.Integer for pro

    Failed to convert property value of type java.lang.String to required type java.lang.Integer for pro ...

  6. Property ‘id‘ not found on type java.lang.String问题解决

    Property 'id' not found on type java.lang.String问题解决 参考文章: (1)Property 'id' not found on type java.l ...

  7. javax.el.PropertyNotFoundException: Property 'xxx' not found on type java.lang.String

    这个错误应该是你从处理器里把数据展示给页面的时候出现的,而且用到了jstl表达式,比如: 此时出现  javax.el.PropertyNotFoundException: Property 'xxx ...

  8. Failed to convert value of type 'java.lang.String' to required type 'java.util.Date

    异常原因:Controller层获取JSP页面请求参数是String类型,而在Controller层接收时使用Date类型,属于方法参数类型不匹配异常 警告: Failed to bind reque ...

  9. spring:Failed to convert property value of type ‘java.lang.String‘ to required type ‘java.util.Date‘

    前言 springboot有接口日期转换的经典问题,给Entity加@JsonFormat解决了输出json日期格式的输入输出问题,但是解决不了非@RequestBody/也就是普通表单提交的日期格式 ...

最新文章

  1. Android 多线程-----AsyncTask详解
  2. nmap脚本(nse)使用总结
  3. 硬盘录像机和服务器,硬盘录像机和视频监控服务器
  4. 第九讲 二阶齐次常系数线性ODE
  5. [云炬python3玩转机器学习笔记] 3-3Numpy数据基础
  6. linux加密框架 crypto 算法管理 - 算法查找接口 crypto_find_alg
  7. C++工作笔记-C++中assert的作用
  8. 数据库连接失败报错com.mysql.cj.jdbc.exceptions.CommunicationsException
  9. Intel 45 纳米处理器加速VMware虚拟架构普及
  10. 博格和他的先锋集团创业史(2):我觉得自己在天堂
  11. 简单对抗神经网络GAN实现与讲解-图片对抗
  12. ​什么是bug?bug的源头在哪里?
  13. 算法基础14 —— 图论入门之弗洛伊德算法(Floyed + Dijkstra + Bellman-Ford + SPFA)
  14. 树模型与python实现
  15. 舵机 - 什么是舵机
  16. Latex证明环境:白方块/黑方块
  17. 计算机网络正常无法打开网页,电脑网络正常但是网页无法打开怎么样解决
  18. 文件上传漏洞揭密剖析(一)-文件上传漏洞原理
  19. html浏览器标题闪动,如何实现网页标题的闪动提示
  20. 2022支付宝集五福活动开始了 有哪些集福方法你知道吗?

热门文章

  1. EXT4文件系统磁盘分布和部分特性介绍
  2. import mxnet 报错
  3. 浙江大学754西医综合
  4. ROS 消息过滤器MessageFilter
  5. jcrop java_SpringMVC结合Jcrop实现图片裁剪
  6. Python(二) 表示‘组’的概念与定义
  7. AutoSAR系列讲解(实践篇)7.5-OS原理进阶(上)
  8. 【物流行业热议】阿里巴巴CTO程立:达摩院和菜鸟启动无人物流卡车研究
  9. 百度地图开发-搭建基础脚手架 01
  10. MyBatis中的JdbcType映射数据类型对照表