Springboot项目中注入bean失败的问题排查

Springboot项目中注入bean失败的问题排查

这是一个Spring常见的问题,下面我们从测试方法和普通方法出问题两个角度来下探讨如何解决

测试方法

先查看目录是否有误

测试类的包名一定要和启动类的包名一致 。

这里盗用一张图,为了避免这个错误我的测试方法大多都是Alt+insert自动生成大体测试框架。

img

继承被测试方法

我们可以通过直接在测试方法上继承对应的被测试类来确保注入Bean成功

image-20230216165628080

普通方法

普通方法解决该问题的内容测试方法同样适用

DI配置注解使用有误

检查是否配置包扫描注解 @ComponentScan

@ComponentScan:该注解添加在启动类上,相当于xml配置中的<context:component-scan base-package=""/> ,注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式{ },如:

@ComponentScan(basePackages = {"com.xuecheng.system","com.xuecheng.web","com.xuecheng.mybatis"}) // 指定启动类包扫描范围

注意:spring只会扫描basePackages做在的包。把相关配置和依赖纳入容易。默认不写的话为包名为springboot启动类Applications所在包

检查是否实例化Bean到Spring容器内

此处注解添加在DI对应类上

  • @Component
    用于实例化对象,相当于配置文件中的<bean id="" class=""/>
    它支持一个属性value,相当于xml中bean的id,如果不写,默认值为类名的首字母小写

  • @Controller @Service @Repository
    这三个注解的功能跟@Component类似,他们分别标注在不同的层上。
    @Controller 标注在表现层(servlet/collecter)的类上
    @Service 标注在业务层(service)的类上
    @Repository 标注在持久层(dao/mapper)的类上,这里我更喜欢用MyBatis提供的@Mapper注解
    实例化时推荐使用这三个更见名知意的,当一个类实在不好归属在这三个层上时,再使用@Component

DI注入有问题

当我们保证上述没有问题时,我们应该考虑是我们DI注入注解有问题,常用的注入DI注解有

  • @Autowired
    根据类型将ioc容器中的对象实例注入进来,按类型装配,相当于:ioc.getBean(Class类型),该属于暴力反射可省略set方法

  • @Qualifier(名称)
    需要与@Autowired一起使用,相当于按名称装配,根据id+类型将ioc容器的对象实例注入进来,相当于:ioc.getBean(id,Class类型)

  • @Resource
    java提供的注解,相当于@Autowired+@Qualifier,相当于按名称装配,但不建议使用

我们从最常用的@Autowired看起

@Autowired

先说错误的、无效的操作,这两个操作只能去掉注入失败的红色下划线,是经典的掩耳盗铃😅

  • 在注解后面添加(required=false)

  • 关闭IDEA的Bean注入检查

常见的@Autowired失效/报错情况有

  • 当标注的属性是接口,而且这个接口有多个实现类时,只使用@Autowired就会报错,因为它默认是根据类型找,然后就会找到多个实现类bean,所有就不知道要注入哪个。然后它就会根据属性名去找。所以如果有多个实现类可以配合@Qualifier(value=“类名”)来使用
  • 使用@Autowired,如果被注入对象声明为static会失效,可以将将@Autowire加到构造方法上来解决。详情参考:SpringBoot之@Autowired和static静态资源
  • springboot中@Autowired 注入失效的四种原因及解决方法)

其他三个注解目前了解的失效的场景较少,留待日后补充

posted @ 2023-02-16 18:08  KMP  阅读(3085)  评论(0编辑  收藏  举报