Spring 使用@ComponentScan 时启动在兄弟包中找不到 JpaRepositories,或者使用@EnableJpaRepositories 时无法初始化它们
Spring boot doesn't find JpaRepositories in sibling-package when using @ComponentScan or can't initialize them when using @EnableJpaRepositories
我有一个由多个模块组成的maven 项目。其中三个模块是
- "project-core"(包含模型 classes)
- "project-data"(包含 Spring 数据 JPA 存储库)
- "project-spring"(包含带有 REST 控制器的主 Spring 引导应用程序)。
启动时出现以下异常:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.foo.bar.data.OrderRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
我知道 Spring 默认情况下引导应用程序只在它们自己的包和它们的子包中查找 bean,但在这种情况下,bean 位于兄弟包中。我已经尝试将 @ComponentScan({"org.foo.bar.data"})
添加到应用程序 class,但无济于事。
使用@EnableJpaRepositories(basePackages = {"org.foo.bar.data"})
抛出
Caused by: java.lang.IllegalArgumentException: Not an managed type: class org.foo.bar.core.model.Order
我做错了什么?
目录树(经过修剪)如下所示:
project
├── project-core
│ └── src
│ └── main
│ └── java
│ └── org
│ └── foo
│ └── bar
│ └── core
| └── model
| └── Order.java
├── project-data
│ └── src
│ └── main
│ └── java
│ └── org
│ └── foo
│ └── bar
│ └── data
| └── OrderRepository.java
│
└── project-spring
└── src
└── main
└── java
└── org
└── foo
└── bar
└── spring
└── Application.java
订单库:
public interface OrderRepository extends JpaRepository<Order, Integer> {
List<Order> findByDeliveryOverview(DeliveryOverview deliveryOverview);
List<Order> findByDeliveryOverviewAndCustomer(DeliveryOverview deliveryOverview, Customer customer);
}
Application.java
@SpringBootApplication
@ComponentScan({"org.foo.bar.data"})
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
主要问题是你的结构。
要扫描实体,您需要 @EntityScan
在您的应用程序 class 上,并启用您需要的存储库 @EnableJpaRepositories
。
@SpringBootApplication
@EntityScan({"org.foo.bar.core.model"})
@EnableJpaRepositories(basePackages = {"org.foo.bar.data"})
public class Application { ... }
但是我建议将 Application
class 移动到 org.foo.bar
然后你只需要 @SpringBootApplication
因为它会从那个目录开始扫描。
用@Repository
注释OrderRepository
并在@ComponentScan
中删除这条语句{"org.foo.bar.data"}
我有一个由多个模块组成的maven 项目。其中三个模块是
- "project-core"(包含模型 classes)
- "project-data"(包含 Spring 数据 JPA 存储库)
- "project-spring"(包含带有 REST 控制器的主 Spring 引导应用程序)。
启动时出现以下异常:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.foo.bar.data.OrderRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
我知道 Spring 默认情况下引导应用程序只在它们自己的包和它们的子包中查找 bean,但在这种情况下,bean 位于兄弟包中。我已经尝试将 @ComponentScan({"org.foo.bar.data"})
添加到应用程序 class,但无济于事。
使用@EnableJpaRepositories(basePackages = {"org.foo.bar.data"})
抛出
Caused by: java.lang.IllegalArgumentException: Not an managed type: class org.foo.bar.core.model.Order
我做错了什么?
目录树(经过修剪)如下所示:
project
├── project-core
│ └── src
│ └── main
│ └── java
│ └── org
│ └── foo
│ └── bar
│ └── core
| └── model
| └── Order.java
├── project-data
│ └── src
│ └── main
│ └── java
│ └── org
│ └── foo
│ └── bar
│ └── data
| └── OrderRepository.java
│
└── project-spring
└── src
└── main
└── java
└── org
└── foo
└── bar
└── spring
└── Application.java
订单库:
public interface OrderRepository extends JpaRepository<Order, Integer> {
List<Order> findByDeliveryOverview(DeliveryOverview deliveryOverview);
List<Order> findByDeliveryOverviewAndCustomer(DeliveryOverview deliveryOverview, Customer customer);
}
Application.java
@SpringBootApplication
@ComponentScan({"org.foo.bar.data"})
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
主要问题是你的结构。
要扫描实体,您需要 @EntityScan
在您的应用程序 class 上,并启用您需要的存储库 @EnableJpaRepositories
。
@SpringBootApplication
@EntityScan({"org.foo.bar.core.model"})
@EnableJpaRepositories(basePackages = {"org.foo.bar.data"})
public class Application { ... }
但是我建议将 Application
class 移动到 org.foo.bar
然后你只需要 @SpringBootApplication
因为它会从那个目录开始扫描。
用@Repository
注释OrderRepository
并在@ComponentScan
{"org.foo.bar.data"}