Rox*_*Rox 14 java spring spring-boot
我有两个Maven模块.第一个名为"application",包含spring boot仅包含以下行的Application类:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
在相同的Maven模块和包中org.example.application,我有一个RestController使用Component它反过来使用下面描述的另一个Maven模块的组件.
另一个称为"模型"的Maven模块包含spring boot组件(crud-repositories,实体等).所有这些类都与第一个Maven模块(org.example)在相同的包结构下,但在其中的子包中,如org.example.model.entities,org.example.model.repositories等等.
所以,流程是这样的:
application包org.example中的 Maven模块:
SpringBootApplication -> RestController -> MyComponent
应该自动装配MyComponent的model组件是包装下的Maven模块中的组件org.example.model.
但是当我启动应用程序时,我只是得到错误:
***************************
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.
Run Code Online (Sandbox Code Playgroud)
org.example.model.repositories.MyRepository 确实存在于Maven模块"model"中,但SpringBootApplication类无法找到它!
正如您所看到的,我已尝试将扫描组件明确定义为:
@ComponentScan({"org.example.model", "org.example"})但这似乎没有帮助.
那我做错了什么?
dav*_*xxx 21
你应该想知道的第一件事是:你为什么要声明@ComponentScan其中一个目标@SpringBootApplication是(除其他事项外)启用组件扫描?
从Spring Boot文档:
该
@SpringBootApplication注解相当于使用@Configuration,@EnableAutoConfiguration并@ComponentScan与他们的默认属性
请注意,当您在Spring Boot Application的类上声明@ComponentScan指定一个值时basePackages,它会覆盖basePackages默认使用的值,@SpringBootApplication即该类所在的当前包.因此,要将Spring Boot Application类的包和缺少的其他包作为基础包,您必须明确设置它们.
除此之外basePackages是递归的.因此,要为位于"org.example"和"org.example.model"包中的类启用扫描,指定"org.example"就足够了,就像"org.example.model"它的子包一样.
试试看:
@SpringBootApplication(scanBasePackages={"org.example"})
Run Code Online (Sandbox Code Playgroud)
或者:
@SpringBootApplication
@ComponentScan("org.example")
Run Code Online (Sandbox Code Playgroud)
在设计Spring Boot应用程序布局时,您有两种情况:
1)case(赞成)你使用一个包布局,它提供Spring Boot的零配置自动配置.
总结:如果你用的Spring bean注解的类定型:@Component,@Repositories,@Repositories,...都位于同一个包或者Spring引导应用程序类的子包,仅声明
@SpringBootApplication是你所需要的.
2)大小写(避免)你不使用的软件包布局提供Spring引导的零配置自动配置.
它通常意味着您有要扫描的候选类,这些类不在您注释的类的包(或子包)中@SpringBootApplication.
在这种情况下,您可以添加scanBasePackages属性或添加@ComponentScan以指定要扫描的包.
但另外,如果您的存储库不在您的类的包或子包中@SpringBootApplication,则必须声明其他内容,例如:@EnableJpaRepositories(="packageWhereMyRepoAreLocated")
80.3使用Spring Data Repositories
Spring Data可以创建各种风格的@Repository接口的实现.Spring Boot会为您处理所有这些,只要这些@Repositories包含在@EnableAutoConfiguration类的同一个包(或子包)中.
对于许多应用程序,您只需要在类路径上放置正确的Spring Data依赖项(对于JPA有一个spring-boot-starter-data-jpa,对于Mongodb有一个spring-boot-starter-data-mongodb)并创建一些存储库接口来处理您的@Entity对象.例子在JPA样本和Mongodb样本中.
Spring Boot会根据找到的@EnableAutoConfiguration尝试猜测@Repository定义的位置.要获得更多控制,请使用@EnableJpaRepositories注释(来自Spring Data JPA).
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);
}
}
Run Code Online (Sandbox Code Playgroud)
存储库可以位于org.example.repository包中,例如:
package org.example.repository;
@Repository
public interface FooRepository extends JpaRepository<Foo, Long>, { }
Run Code Online (Sandbox Code Playgroud)
和
package org.example.repository;
@Repository
public interface BarRepository extends JpaRepository<Bar, Long>, { }
Run Code Online (Sandbox Code Playgroud)
控制器可以位于org.example.controller包装中:
package org.example.controller;
@RestController
@RequestMapping("/api/foos")
public class FooController {...}
Run Code Online (Sandbox Code Playgroud)
等......
2)大小写(避免)你不使用的软件包布局提供Spring引导的零配置自动配置.
使用在org.example.application包中声明的Spring Boot应用程序,而不是在同一个包或子包中org.example.application声明的所有bean类(包含的存储库),Spring Boot应用程序将需要以下声明:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
bean类可以如下所示.
可能来自外部JAR的存储库可以位于org.thirdparty.repository包中,例如:
package org.thirdparty.repository;
@Repository
public interface FooRepository extends JpaRepository<Foo, Long>, { }
Run Code Online (Sandbox Code Playgroud)
和
package org.thirdparty.repository;
@Repository
public interface BarRepository extends JpaRepository<Bar, Long>, { }
Run Code Online (Sandbox Code Playgroud)
控制器可以位于org.example.controller包装中:
package org.example.controller
@RestController
@RequestMapping("/api/foos")
public class FooController {...}
Run Code Online (Sandbox Code Playgroud)
等......
结束语:我们鼓励在命名空间的基础包中定义Spring Boot应用程序,以使Spring Boot配置尽可能简单.