记一次依赖三方jar包或者自己的模块时无法自动注入问题
问题:第三方jar或自己的模块均属于spring项目,但是项目无法启动,提示expected at least 1 bean which qualifies as autowire candidate
经排查发现,项目所依赖的另外一个模块,两边的包名不一致,导致spring在启动时无法扫描到依赖模块包目录下的类,导致无法自动注入
解决
- 自己依赖的项目是spring项目,可以通过
@ComponentScan
注解指定包名,来达到扫描自动注入的目的 - 当项目不是spring项目即没有被spring相关注解标识的,可以使用
@Configuration
手动注入相关依赖
以上两种均可使用,个人推荐使用方式2,避免包扫描带来的一些冲突,以及启动了三方模块不该启动的功能
引申出@ComponentScan
注解的基础用法
默认包扫描行为
默认包: @ComponentScan 什么也不填时,Spring 会扫描所在类的包及其子包。换句话说,Spring 会从声明 @ComponentScan 注解的类所在的包开始进行扫描。
例子: 假设你的启动类在包 com.example.app 下,并且使用了 @ComponentScan 注解,那么 Spring 会扫描 com.example.app 包及其所有子包。
com
└── example
└── app
├── Application.java
├── service
│ └── MyService.java
└── controller
└── MyController.java
在这种结构下,如果 Application.java 是你的启动类,并且你没有为 @ComponentScan 注解指定任何包路径:
package com.example.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan // 没有指定包路径
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
那么 Spring 会自动扫描 com.example.app 包及其子包,即 com.example.app.service 和 com.example.app.controller 包。
指定包路径
如果你想要扫描特定的包,可以在 @ComponentScan 注解中指定包路径:
@ComponentScan("com.example.app.service")
这样,Spring 只会扫描 com.example.app.service 包及其子包,而不会扫描其他包。
多个包路径
你也可以指定多个包路径:
@ComponentScan({"com.example.app.service", "com.example.app.controller"})
这样,Spring 会扫描 com.example.app.service 和 com.example.app.controller 包及其子包。
总结
- 如果 @ComponentScan 没有指定任何包路径,Spring 会从声明此注解的类所在的包及其子包开始进行扫描。
- 你可以通过在 @ComponentScan 注解中指定包路径来控制 Spring 扫描的范围。
评论区