java 多模块项目的 SpringBoot ComponentScan 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30587377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:20:53  来源:igfitidea点击:

SpringBoot ComponentScan issue with multi-module project

javaspringspring-boot

提问by K. Siva Prasad Reddy

I have a myapp parent pom type maven project with myapp-core and myapp-web modules. myapp-core module is added as dependency to myapp-web.

我有一个带有 myapp-core 和 myapp-web 模块的 myapp 父 pom 类型 maven 项目。myapp-core 模块作为依赖项添加到 myapp-web。

All the classes in myapp-core module reside in root package com.myapp.coreand all classes in myapp-web module reside in root package com.myapp.web

myapp-core 模块中的所有类都驻留在根包com.myapp.core 中,而 myapp-web 模块中的所有类都驻留在根包com.myapp.web 中

The main Application.java is also in com.myapp.web package. As my core module root package is different I am including common base package "com.myapp"for ComponentScan as follows:

主 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);
    }   
}

Now the surprising thing is if I run this app using Run As -> Spring Boot Appit is working fine. But if I run it as Run As -> Java Applicationit is failing with error saying it can't found beans defined in myapp-core module.

现在令人惊讶的是,如果我使用Run As -> Spring Boot App运行这个应用程序,它运行良好。但是,如果我将它作为Run As -> Java Application 运行,它会失败并显示错误,说它找不到 myapp-core 模块中定义的 bean。

If I move my Application.javato com.myapppackage it is working fine. It should work even if i run it as Java Application also, right?

如果我移动我Application.javacom.myapp包装它工作正常。即使我也将它作为 Java 应用程序运行,它也应该可以工作,对吗?

回答by K. Siva Prasad Reddy

After enabling debug log level for spring and going through extensive logs I found that scanning for various components like JPA Repositories, JPA Entities etc are depending on the Application.java's package name.

在为 spring 启用调试日志级别并查看大量日志后,我发现对 JPA 存储库、JPA 实体等各种组件的扫描取决于 Application.java 的包名称。

If the JPA Repositories or Entities are not in sub packages of Application.java's package then we need to specify them explicitly as follows:

如果 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);
    }
}

With the above additional @EnableJpaRepositories, @EntityScanI am able to run it using Run As -> Java Application.

有了上面的附加功能@EnableJpaRepositories@EntityScan我就可以使用Run As -> Java Application来运行它。

But still not sure how it is working fine when Run As -> Spring Boot App!!

但是仍然不确定在Run As -> Spring Boot App时它是如何正常工作的!!

Anyway I think it is better to move my Application.javato com.myapppackage rather than fighting with SpringBoot!

无论如何我认为最好将我Application.javacom.myapp打包而不是与SpringBoot战斗!

回答by Raymond

I have the same problem. Only adding the @EnableJpaRepositories annotation can solve the issue. I tried to define basePackages in @SpringBootApplication, to no avail. I think the package of the Application class is fed to the scanning process of JpaRepositories, but other packages defined in @SpringBootApplication are ignored. It looks like a bug/improvement of Spring Boot.

我也有同样的问题。只有添加@EnableJpaRepositories 注解才能解决问题。我试图在@SpringBootApplication 中定义 basePackages,但无济于事。我认为Application类的包被馈送到JpaRepositories的扫描过程,但@SpringBootApplication中定义的其他包被忽略了。它看起来像是 Spring Boot 的错误/改进。

回答by theINtoy

I had a similar issue with Redis repositories that was fixed in a similar way:

我在 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;
    }
}