Spring Boot 框架本身并没有对工程结构有特别的要求, 但是按照最佳实践的工程结构可以帮助我们减少可能会遇见的坑, 尤其是 Spring 包扫描机制的存在, 如果您使用最佳实践的工程结构, 可以免去不少特殊的配置工作.
典型示例
以下结构是比较推荐的 package 组织方式:
- com
- +- example
- +- myproject
- +- Application.java
- |
- +- domain
- | +- Customer.java
- | +- CustomerRepository.java
- |
- +- service
- | +- CustomerService.java
- |
- +- web
- | +- CustomerController.java
- |
- root package:
- com.example.myproject
, 所有的类和其他 package 都在 root package 之下.
应用主类: Application.java, 该类直接位于 root package 下. 通常我们会在应用主类中做一些框架配置扫描等配置, 我们放在 root package 下可以帮助程序减少手工配置来加载到我们希望被 Spring 加载的内容
com.example.myproject.domain
包: 用于定义实体映射关系与数据访问相关的接口和实现
com.example.myproject.service
包: 用于编写业务逻辑相关的接口与实现
com.example.myproject.Web
: 用于编写 Web 层相关的实现, 比如: Spring MVC 的 Controller 等
上面的结构中, root package 与应用主类的位置是整个结构的关键. 由于应用主类在 root package 中, 所以按照上面的规则定义的所有其他类都处于 root package 下的其他子包之后. 默认情况下, Spring Boot 的应用主类会自动扫描 root package 以及所有子包下的所有类来进行初始化.
什么意思呢? 举个例子, 假设我们将 com.example.myproject.Web 包与上面所述的 root package:com.example.myproject 放在同一级, 像下面这样:
- com
- +- example
- +- myproject
- +- Application.java
- |
- +- domain
- | +- Customer.java
- | +- CustomerRepository.java
- |
- +- service
- | +- CustomerService.java
- |
- +- Web
- | +- CustomerController.java
- |
这个时候, 应用主类 Application.java 在默认情况下就无法扫描到 com.example.myproject.Web 中的 Controller 定义, 就无法初始化 Controller 中定义的接口.
非典型结构下的初始化
那么如果, 我们一定要加载非 root package 下的内容怎么办呢?
方法一: 使用 @ComponentScan 注解指定具体的加载包, 比如:
- @SpringBootApplication
- @ComponentScan(basePackages="com.example")
- public class Bootstrap {
- public static void main(String[] args) {
- SpringApplication.run(Bootstrap.class, args);
- }
- }
这种方法通过注解直接指定要扫描的包, 比较直观. 如果有这样的需求也是可以用的, 但是原则上还是推荐以上面的典型结构来定义, 这样也可以少写一些注解, 代码更加简洁.
方法二: 使用 @Bean 注解来初始化, 比如:
- @SpringBootApplication
- public class Bootstrap {
- public static void main(String[] args) {
- SpringApplication.run(Bootstrap.class, args);
- }
- @Bean
- public CustomerController customerController() {
- return new CustomerController();
- }
- }
这种方法在业务开发的时候并不是特别推荐, 更适合用于框架封装等场景, 关于更多封装上的技巧, 后面我们在进阶教程中详细讲解.
如果读者觉得自己团队使用的工程结构不错, 欢迎留言分享~
代码示例
本教程配套仓库:
GitHub:
Gitee:
如果您觉得本文不错, 欢迎 Star 支持, 您的关注是我坚持的动力!
来源: https://www.cnblogs.com/didispace/p/10709997.html