Spring Boot scanBasePackages无法从依赖项中找到bean
Posted
技术标签:
【中文标题】Spring Boot scanBasePackages无法从依赖项中找到bean【英文标题】:Spring Boot scanBasePackages unable to find beans from dependency 【发布时间】: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.package
,com.my.package.mylibrary
中显示几个类!
请添加显示的错误信息
@SpringBootApplication 注解等效于使用 Configuration、EnableAutoConfiguration 和 ComponentScan 及其默认属性:[...]。如果没有定义特定的包,将从声明该注解的类的包开始扫描。
但是它无法检测到依赖jar中的bean。
阅读此***.com/questions/33619532/…
【参考方案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);
【讨论】:
以上是关于Spring Boot scanBasePackages无法从依赖项中找到bean的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?
《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》