-2

我的应用程序包含以下类:
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 需要找不到类型为“com.foo.bar.ClassToAutowire”的 bean。

行动:

考虑在你的配置中定义一个 'com.foo.bar.ClassToAutowire' 类型的 bean。

我猜 Spring 不喜欢我的包结构?

com.foo.bar.ClassToAutowire
com.foo.appl.SpringMainApplication
com.foo.appl.pack.ImplementationClass

是否@SpringBootApplication必须在根包中并且所有组件都必须在子包中?如果是这样,我该如何解决我的“问题”,因为ClassToAutowire它来自导入的 JAR。

当更改basePackgecom.foo.bar应用程序启动时,但计划的方法将不会运行。

谢谢

4

3 回答 3

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。当使用/添加不同的框架时,这会增长,当您将类放在顶级包中时,情况并非如此,因为所有包都被考虑在内。

于 2017-08-22T09:42:56.223 回答
0

@SpringBootApplication 是否必须在根包中并且所有组件都必须在子包中?不,@SpringBootApplication 可以放在任何地方,但您需要在 @ComponentScan 中提供正确的路径

如果 ClassToAutowire 类的实现来自外部包,则需要从该 jar 导入 spring 配置。这意味着定义使用@Configuration 注释的配置类,然后使用@Import 注释将此配置导入您的ImplementationClass。此处描述的另一个使用弹簧自动配置的 woulb:https ://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html

于 2017-08-22T07:47:57.450 回答
0

您应该实现接口 com.foo.bar.ClassToAutowire并使用@Component注释类

@Component表示一个带注释的类是一个“组件”。在使用基于注释的配置和类路径扫描时,此类类被视为自动检测的候选对象。 参考@Component 文档

于 2017-08-22T07:57:54.750 回答