Spring ComponentScan 包结构
Spring ComponentScan package-structure
我的应用程序包含以下 classes:
Spring主要应用程序:
@SpringBootApplication
@ComponentScan(basePackages = {"com.foo"})
class com.foo.appl.SpringMainApplication {
... some code...
}
应该用于自动装配字段的接口:
interface com.foo.bar.ClassToAutowire {
}
还有另一个 class 对字段使用所述接口:
@Component
class com.foo.appl.pack.ImplementationClass {
@Autowired
ClassToAutowire autoClass;
@Scheduled(fixedRate = 60000)
public void startStuff() {
// do something...
}
}
但该字段不会自动装配:
Field autoClass in com.foo.appl.pack.ImplementationClass required a
bean of type 'com.foo.bar.ClassToAutowire' that could not be found.
Action:
Consider defining a bean of type 'com.foo.bar.ClassToAutowire' in your
configuration.
我想 Spring 不喜欢我的包结构?
com.foo.bar.ClassToAutowire
com.foo.appl.SpringMainApplication
com.foo.appl.pack.ImplementationClass
是否 @SpringBootApplication
必须在根包中并且所有组件都必须在子包中?如果是这样,我该如何解决我的 "problem",因为 ClassToAutowire
来自导入的 JAR。
当将 basePackge
更改为 com.foo.bar
时,应用程序启动,但计划的方法不会 运行。
谢谢
@SpringBootApplication是否必须在根包中,所有组件都必须在子包中?不,@SpringBootApplication可以放在任何地方,但你需要提供正确的@ComponentScan
中的路径
如果 ClassToAutowire class 的实现来自外部包,您将需要从该 jar 导入 spring 配置。这意味着定义使用 @Configuration 注释的配置 class,然后使用 @Import 注释将此配置导入您的 ImplementationClass 中。
此处描述的另一个使用 spring 自动配置的方法:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
您应该实现 接口 com.foo.bar.ClassToAutowire 并使用 @Component
注释 class
@Component 表示一个注解的class是一个"component"。在使用基于注释的配置和 class 路径扫描时,此类 classes 被视为自动检测的候选对象。
reference @Component documentation
当使用Spring 时,默认启动它进行组件扫描。此组件扫描是在与 @SpringBootApplication
注释 class 所在的同一包中开始完成的。在您的情况下是 com.foo.appl
但这不包括 com.foo.bar
.
最佳做法是将您的 @SpringBootApplication
注释 class 放在您能找到的最顶级包中,在您的情况下是 com.foo
。这将扫描其下的所有包并将包括适当的组件。
您还可以将 @ComponentScan("com.foo")
添加到您的 @SpringBootApplication
注释 class 以让它开始扫描不同的包裹或 (@SpringBootApplication(basePackage="com.foo")
。
如果依赖 jar 中不再有组件,您还可以添加一个 @Bean
方法来创建所需 class 的实例。
@Bean
public ClassToAutowire classToAutowire() {
return new ClassToAutowire();
}
第二种方法的缺点是,当使用 Spring Data 或 JPA 之类的东西时,您还必须手动配置它们(添加 @EnableJpaRepositories
和 @EntityScan
之类的东西)。当 using/adding 不同的框架时,这会增长,当您将 class 放在顶级包中时情况并非如此,因为所有包都被考虑在内。
我的应用程序包含以下 classes:
Spring主要应用程序:
@SpringBootApplication
@ComponentScan(basePackages = {"com.foo"})
class com.foo.appl.SpringMainApplication {
... some code...
}
应该用于自动装配字段的接口:
interface com.foo.bar.ClassToAutowire {
}
还有另一个 class 对字段使用所述接口:
@Component
class com.foo.appl.pack.ImplementationClass {
@Autowired
ClassToAutowire autoClass;
@Scheduled(fixedRate = 60000)
public void startStuff() {
// do something...
}
}
但该字段不会自动装配:
Field autoClass in com.foo.appl.pack.ImplementationClass required a bean of type 'com.foo.bar.ClassToAutowire' that could not be found.
Action:
Consider defining a bean of type 'com.foo.bar.ClassToAutowire' in your configuration.
我想 Spring 不喜欢我的包结构?
com.foo.bar.ClassToAutowire
com.foo.appl.SpringMainApplication
com.foo.appl.pack.ImplementationClass
是否 @SpringBootApplication
必须在根包中并且所有组件都必须在子包中?如果是这样,我该如何解决我的 "problem",因为 ClassToAutowire
来自导入的 JAR。
当将 basePackge
更改为 com.foo.bar
时,应用程序启动,但计划的方法不会 运行。
谢谢
@SpringBootApplication是否必须在根包中,所有组件都必须在子包中?不,@SpringBootApplication可以放在任何地方,但你需要提供正确的@ComponentScan
中的路径如果 ClassToAutowire class 的实现来自外部包,您将需要从该 jar 导入 spring 配置。这意味着定义使用 @Configuration 注释的配置 class,然后使用 @Import 注释将此配置导入您的 ImplementationClass 中。 此处描述的另一个使用 spring 自动配置的方法:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
您应该实现 接口 com.foo.bar.ClassToAutowire 并使用 @Component
注释 class@Component 表示一个注解的class是一个"component"。在使用基于注释的配置和 class 路径扫描时,此类 classes 被视为自动检测的候选对象。 reference @Component documentation
当使用Spring 时,默认启动它进行组件扫描。此组件扫描是在与 @SpringBootApplication
注释 class 所在的同一包中开始完成的。在您的情况下是 com.foo.appl
但这不包括 com.foo.bar
.
最佳做法是将您的 @SpringBootApplication
注释 class 放在您能找到的最顶级包中,在您的情况下是 com.foo
。这将扫描其下的所有包并将包括适当的组件。
您还可以将 @ComponentScan("com.foo")
添加到您的 @SpringBootApplication
注释 class 以让它开始扫描不同的包裹或 (@SpringBootApplication(basePackage="com.foo")
。
如果依赖 jar 中不再有组件,您还可以添加一个 @Bean
方法来创建所需 class 的实例。
@Bean
public ClassToAutowire classToAutowire() {
return new ClassToAutowire();
}
第二种方法的缺点是,当使用 Spring Data 或 JPA 之类的东西时,您还必须手动配置它们(添加 @EnableJpaRepositories
和 @EntityScan
之类的东西)。当 using/adding 不同的框架时,这会增长,当您将 class 放在顶级包中时情况并非如此,因为所有包都被考虑在内。