多模块项目的 Spring Component Scan 问题
SpringBoot ComponentScan issue with multi-module project
我有一个带有 myapp-core 和 myapp-web 模块的 myapp 父 pom 类型 maven 项目。 myapp-core 模块添加为 myapp-web 的依赖项。
myapp-core 模块中的所有 类 位于根包 com.myapp.core 中,myapp-web 模块中的所有 类 位于根包 com.myapp.web
主要的 Application.java 也在 com.myapp.web 包中。由于我的核心模块根包不同,我为 ComponentScan 包含了通用基础包 "com.myapp",如下所示:
@Configuration
@ComponentScan(basePackages="com.myapp")
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
现在令人惊讶的是,如果我 运行 这个应用程序使用 运行 As -> Spring Boot App 它工作正常。但是如果我 运行 它作为 运行 As -> Java Application 它失败并显示错误说它找不到在 myapp 中定义的 beans-核心模块。
如果我将我的 Application.java
移动到 com.myapp
包,它工作正常。
即使我 运行 它也应该作为 Java 应用程序工作,对吗?
在为 spring 启用调试日志级别并查看大量日志后,我发现扫描各种组件(如 JPA 存储库、JPA 实体等)取决于 Application.java 的包名称。
如果 JPA 存储库或实体不在 Application.java
包的子包中,那么我们需要明确指定它们,如下所示:
@Configuration
@ComponentScan(basePackages="com.sivalabs.jcart")
@EnableAutoConfiguration
@EnableJpaRepositories(basePackages="com.sivalabs.jcart")
@EntityScan(basePackages="com.sivalabs.jcart")
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
有了上面的附加 @EnableJpaRepositories
,@EntityScan
我可以 运行 使用 运行 As -> Java 应用程序.
但仍然不确定当 运行 As -> Spring Boot App!!
时它是如何正常工作的
无论如何,我认为最好将我的 Application.java
移动到 com.myapp
包而不是与 SpringBoot!
战斗
我也遇到了同样的问题。只有添加@EnableJpaRepositories 注解才能解决问题。我试图在@SpringBootApplication 中定义basePackages,但无济于事。
我认为 Application class 的包被馈送到 JpaRepositories 的扫描过程,但是 @SpringBootApplication 中定义的其他包被忽略了。
它看起来像 bug/improvement 的 Spring Boot.
我在 Redis 存储库中遇到了类似的问题,该问题已以类似的方式修复:
@Configuration
@EnableConfigurationProperties({RedisProperties.class})
@RequiredArgsConstructor
@EnableRedisRepositories(basePackages = {"com.example.another"})
public class RedisConfig {
private final RedisConnectionFactory redisConnectionFactory;
@Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
template.setConnectionFactory(redisConnectionFactory);
template.afterPropertiesSet();
return template;
}
}
我有一个带有 myapp-core 和 myapp-web 模块的 myapp 父 pom 类型 maven 项目。 myapp-core 模块添加为 myapp-web 的依赖项。
myapp-core 模块中的所有 类 位于根包 com.myapp.core 中,myapp-web 模块中的所有 类 位于根包 com.myapp.web
主要的 Application.java 也在 com.myapp.web 包中。由于我的核心模块根包不同,我为 ComponentScan 包含了通用基础包 "com.myapp",如下所示:
@Configuration
@ComponentScan(basePackages="com.myapp")
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
现在令人惊讶的是,如果我 运行 这个应用程序使用 运行 As -> Spring Boot App 它工作正常。但是如果我 运行 它作为 运行 As -> Java Application 它失败并显示错误说它找不到在 myapp 中定义的 beans-核心模块。
如果我将我的 Application.java
移动到 com.myapp
包,它工作正常。
即使我 运行 它也应该作为 Java 应用程序工作,对吗?
在为 spring 启用调试日志级别并查看大量日志后,我发现扫描各种组件(如 JPA 存储库、JPA 实体等)取决于 Application.java 的包名称。
如果 JPA 存储库或实体不在 Application.java
包的子包中,那么我们需要明确指定它们,如下所示:
@Configuration
@ComponentScan(basePackages="com.sivalabs.jcart")
@EnableAutoConfiguration
@EnableJpaRepositories(basePackages="com.sivalabs.jcart")
@EntityScan(basePackages="com.sivalabs.jcart")
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
有了上面的附加 @EnableJpaRepositories
,@EntityScan
我可以 运行 使用 运行 As -> Java 应用程序.
但仍然不确定当 运行 As -> Spring Boot App!!
时它是如何正常工作的无论如何,我认为最好将我的 Application.java
移动到 com.myapp
包而不是与 SpringBoot!
我也遇到了同样的问题。只有添加@EnableJpaRepositories 注解才能解决问题。我试图在@SpringBootApplication 中定义basePackages,但无济于事。 我认为 Application class 的包被馈送到 JpaRepositories 的扫描过程,但是 @SpringBootApplication 中定义的其他包被忽略了。 它看起来像 bug/improvement 的 Spring Boot.
我在 Redis 存储库中遇到了类似的问题,该问题已以类似的方式修复:
@Configuration
@EnableConfigurationProperties({RedisProperties.class})
@RequiredArgsConstructor
@EnableRedisRepositories(basePackages = {"com.example.another"})
public class RedisConfig {
private final RedisConnectionFactory redisConnectionFactory;
@Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>();
template.setConnectionFactory(redisConnectionFactory);
template.afterPropertiesSet();
return template;
}
}