java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件
|
我有两个Maven模块.
package org.example.application;
@SpringBootApplication
@ComponentScan({"org.example.model","org.example"})
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class,args);
}
}
在同一个Maven模块和包org.example.application中,我有一个使用Component的RestController,而Component又使用下面描述的另一个Maven模块的组件. 另一个名为“model”的Maven模块包含spring引导组件(crud-repositories,实体等).所有这些类都与第一个Maven模块(org.example)在相同的包结构下,但在其子包中,如org.example.model.entities,org.example.model.repositories等. 所以,流程是这样的: 包org.example中的Maven模块应用程序: 应该在MyComponent中自动装配的组件是包org.example.model下的模型Maven模块中的组件. 但是当我启动应用程序时,我只是得到错误: *************************** APPLICATION FAILED TO START *************************** Description: Field myRepository in org.example.MyComponent required a bean of type 'org.example.model.repositories.MyRepository' that could not be found. Action: Consider defining a bean of type 'org.example.model.repositories.MyRepository' in your configuration. org.example.model.repositories.MyRepository确实存在于Maven模块“model”中,但是SpringBootApplication类找不到它! 如您所见,我尝试将扫描组件明确定义为: 那我做错了什么? 解决方法你应该想知道的第一件事是:为什么你声明@ComponentScan而@SpringBootApplication的目标之一是(除其他事项外)启用组件扫描?从 Spring Boot documentation开始:
请注意,在Spring Boot Application的类上,声明@ComponentScan将值指定为basePackages,它会覆盖默认情况下由@SpringBootApplication使用的basePackages,它是类所在的当前包.因此,要将Spring Boot Application类的包和缺少的其他包作为基础包,您必须明确设置它们. 除了basePackages是递归的.因此,要为位于“org.example”和“org.example.model”包中的类启用扫描,指定“org.example”就足够了,因为“org.example.model”是它的子包. 试试看: @SpringBootApplication(scanBasePackages={"org.example"})
或者: @SpringBootApplication
@ComponentScan("org.example")
在Spring Boot应用程序中指定@ EnableJpaRepositories / @ ComponentScan / scanBasePackages? 在设计Spring Boot应用程序布局时,您有两种情况: 1)case(赞成)你使用一个包布局,它提供Spring Boot的零配置自动配置. 总结一下:如果您的类使用Spring Bean构造型注释:@ Component,@ Storage,@ Repositories,…位于Spring Boot Application类的相同包或子包中,仅声明 2)大小写(避免)你不使用的软件包布局提供Spring引导的零配置自动配置. 它通常意味着您有要扫描的候选类,这些类不在使用@SpringBootApplication注释的类的包(或子包)中. 关于这部分的Here is the documentation(重点是我的):
例子 1)case(赞成)你使用一个包布局,它提供Spring Boot的零配置自动配置. 使用在org.example包中声明的Spring Boot应用程序,以及在同一个包或org.example的子包中声明的所有bean类(包含的存储库),以下声明对于Spring Boot应用程序来说已经足够了: package org.example;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class,args);
}
}
存储库可以位于org.example.repository包中,例如: package org.example.repository;
@Repository
public interface FooRepository extends JpaRepository<Foo,Long>,{ }
和 package org.example.repository;
@Repository
public interface BarRepository extends JpaRepository<Bar,{ }
控制器可以位于org.example.controller包中: package org.example.controller;
@RestController
@RequestMapping("/api/foos")
public class FooController {...}
等…… 2)大小写(避免)你不使用的软件包布局提供Spring引导的零配置自动配置. 使用org.example.application包中声明的Spring Boot应用程序,而不是在同一个包或org.example.application的子包中声明的所有bean类(包含的存储库),Spring将需要以下声明:启动应用: package org.example.application;
@SpringBootApplication(scanBasePackages= {
"org.example","org.thirdparty.repository"})
@EnableJpaRepositories("org.thirdparty.repository")
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class,args);
}
}
bean类可以如下所示. 可能来自外部JAR的存储库可以位于org.thirdparty.repository包中,例如: package org.thirdparty.repository;
@Repository
public interface FooRepository extends JpaRepository<Foo,{ }
和 package org.thirdparty.repository;
@Repository
public interface BarRepository extends JpaRepository<Bar,{ }
控制器可以位于org.example.controller包中: package org.example.controller
@RestController
@RequestMapping("/api/foos")
public class FooController {...}
等…… 结束语:我们鼓励在命名空间的基础包中定义Spring Boot应用程序,以使Spring Boot配置尽可能简单. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
