我的申请包括以下课程:
SpringMainApplication:
@SpringBootApplication
@ComponentScan(basePackages = {"com.foo"})
class com.foo.appl.SpringMainApplication {
... some code...
}
应该用于自动装配字段的接口:
interface com.foo.bar.ClassToAutowire {
}
另一个使用字段接口的类:
@Component
class com.foo.appl.pack.ImplementationClass {
@Autowired
ClassToAutowire autoClass;
@Scheduled(fixedRate = 60000)
public void startStuff() {
// do something...
}
}
但是这个领域不会自动化:
com.foo.appl.pack.ImplementationClass中的字段autoClass需要a bean类型' com.foo.bar.ClassToAutowire'无法找到。
动作:
考虑定义类型' com.foo.bar.ClassToAutowire'在你的 配置。
我猜Spring不喜欢我的包结构吗?
com.foo.bar.ClassToAutowire
com.foo.appl.SpringMainApplication
com.foo.appl.pack.ImplementationClass
@SpringBootApplication
是否必须位于根包中,并且所有组件都必须位于子包中?如果是这样,我如何解决我的问题",因为ClassToAutowire
来自导入的JAR。
将应用程序启动时basePackge
更改为com.foo.bar
,但预定的方法无法运行。
由于
答案 0 :(得分:1)
使用Spring Boot时,默认情况下会进行组件扫描。此组件扫描是在@SpringBootApplication
带注释的类所在的包中开始完成的。在您的情况下为com.foo.appl
,但这不包括com.foo.bar
。
最佳做法是将@SpringBootApplication
带注释的类放在您可以找到的最顶级包中,在您的情况下为com.foo
。这将扫描其下的所有包,并包含适当的组件。
您还可以将@ComponentScan("com.foo")
添加到@SpringBootApplication
带注释的课程中,让它开始在其他包裹上进行扫描或(@SpringBootApplication(basePackage="com.foo")
。
如果依赖关系jar中不再有组件,您还可以添加@Bean
方法来创建所需类的实例。
@Bean
public ClassToAutowire classToAutowire() {
return new ClassToAutowire();
}
第二种方法的缺点是,当使用Spring Data或JPA之类的东西时,您还需要手动配置(添加@EnableJpaRepositories
和@EntityScan
之类的东西)。当使用/添加不同的框架时,这会增长,当您将类放在顶级包中时,并不是这样,因为考虑了所有包。
答案 1 :(得分:0)
@SpringBootApplication是否必须在根包中,并且所有组件都必须在子包中?不,@ SpringBootApplication可以放在任何地方,但是你需要在@ComponentScan中提供正确的路径< / p>
如果ClassToAutowire类的实现来自外部包,则需要从该jar导入spring配置。这意味着定义使用@Configuration注释的配置类,然后使用@Import注释在ImplementationClass中导入此配置。 另一个使用弹簧自动配置的woulb:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
答案 2 :(得分:0)
您应该实现 interface com.foo.bar.ClassToAutowire 并使用 @Component
注释该类@Component 表示带注释的类是“组件”。当使用基于注释的配置和类路径扫描时,这些类被视为自动检测的候选者。 reference @Component documentation