【问题标题】:Spring Boot scanBasePackages unable to find beans from dependencySpring Boot scanBasePackages无法从依赖项中找到bean
【发布时间】:2020-10-02 21:45:07
【问题描述】:

我有以下内容:

@SpringBootApplication(scanBasePackages = {"com.my.package","com.my.package.mylibrary"})
@EnableAsync
@EnableSwagger2
@ServletComponentScan
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class})
public class MySpringBootApplication {....}

这个应用程序有包com.my.package,它还有一个包含我想在这个应用程序中自动装配的spring bean的库依赖项,这些bean在库内的包com.my.package.mylibrary中。

所以我把两者都放在scanBasePackages 上。但是 Spring 无法从库中找到 bean?

编辑:

从图书馆,我有:

package com.my.package.mylibrary.repository;
....
public interface MyRepository extends JpaRepository<..., ....> {....}

在申请中,我有:

package com.my.package.controller;
....
@RestController
public class MyController {....}

MySpringBootApplication 驻留在 com.my.package 中。

错误:

Exception in thread "main" java.lang.NoClassDefFoundError: com/my/package/mylibrary/repository/MyRepository
    at com.my.package.MySpringBootApplication.main(MySpringBootApplication.java:32)
Caused by: java.lang.ClassNotFoundException: com.my.package.mylibrary.repository.MyRepository
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

我为存储库包添加了@EnableJpaRepositories。现在我看到与 MyRepository 所基于的实体 MyEntity 相关的错误。

"java.lang.TypeNotPresentException: Type com.my.package.mylibrary.domain.MyEntity not present

所以我为“com.my.package.mylibrary.domain”添加了@EntityScan,但这会使应用程序无限卡住。

【问题讨论】:

  • 让我们在包com.my.packagecom.my.package.mylibrary中显示几个类!
  • 请添加显示的错误信息
  • @SpringBootApplication 注解等效于使用 Configuration、EnableAutoConfiguration 和 ComponentScan 及其默认属性:[...]。如果没有定义特定的包,将从声明该注解的类的包开始扫描。
  • 但是它无法检测到依赖jar中的bean。

标签: java spring spring-boot


【解决方案1】:

首先,您不需要在@SpringBootApplication 中添加scanBasePackages 属性,因为基础包是com.my.package

如果包完全不同,那么您可以添加它。

如果基础包相同,Spring Boot 会自动拾取 bean。

在编写代码时应该遵循一种称为关注点分离的东西。


将您的 MySpringBootApplication 类更新为:

@SpringBootApplication
@ServletComponentScan
public class MySpringBootApplication {....}

为异步方法执行创建一个单独的配置。

 @Configuration
 @EnableAsync
 public class AsynchronousConfig {.....}

为 Swagger 2 创建一个单独的配置类。

@Configuration
@EnableSwagger2
public class SwaggerConfiguration {....}

创建单独的配置以排除配置。

@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, 
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
public class ExcludeConfigurationFile {....}

注意: Spring boot 自动配置会自动拾取这些@Configuration 文件

这应该可行。

【讨论】:

  • 我已删除 ServletComponentScan。 EntityScan 和 EnableJpaRepositories。我仍然看到 java.lang.TypeNotPresentException: Type com.my.package.mylibrary.domain.MyEntity 不存在。不知何故,spring 无法加载实体类。
  • @Mandroid 你有这个实体 com.my.package.mylibrary.domain.MyEntity 吗?
  • 是的。 MyRepository 是为它定义的。
  • @Mandroid 添加 com.my.package.mylibrary.domain.MyEntity 的代码 ?
  • @Mandroid 检查 MyEntity 类是否存在?
【解决方案2】:

您可能希望单独扫描包并将您的 JpaRepository 更改为 CrudRepository。分层配置如下。

@SpringBootApplication(scanBasePackages = {"com.my.package.controller"})
@EnableJpaRepositories(basePackages = {"com.my.package.mylibrary.repository"})
@EntityScan(basePackages = {"com.my.package.mylibrary.domain"})
public class MySpringBootApplication {

    public static void main(String[] args) {
        MySpringBootApplication.run(MySpringBootApplication.class, args);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-28
    • 2020-03-31
    • 2020-11-11
    • 2021-04-29
    • 2022-01-23
    • 2017-05-17
    • 2018-05-13
    • 2020-07-08
    相关资源
    最近更新 更多