java – 在Spring Boot应用程序中扫描不同maven模块/ JAR的组件
我有两个Maven模块.
第一个名为“application”,包含仅包含以下行的 Spring引导应用程序类: 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配置尽可能简单. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |