8.组织你的代码

Spring Boot不需要使用任何特殊的代码结构,然而,这里有一些有用的最佳实践。

使用"default"包

  • 当类没有包含 package 声明时,它被认为处于 default package 下。通常不推荐使用default package ,并应该避免使用它。因为对于使用 @ComponentScan , @EntityScan 或 @SpringBootApplication 注解的Spring Boot应用来说,来自每个jar的类都会被读取,这会造成一定的问题。

注:我们建议你遵循Java推荐的包命名规范,使用一个反转的域名(例如 com.example.project )。

定位main应用类

  • 我们通常建议你将main应用类放在位于其他类上面的根包(root package)中。通常使用 @EnableAutoConfiguration 注解你的main类,并且暗地里为某些项定义了一个基础“search package”。
  • 例如,如果你正在编写一个JPA应用,被@EnableAutoConfiguration 注解的类所在包将被用来搜索 @Entity 项。
  • 使用根包允许你使用 @ComponentScan 注解而不需要定义一个 basePackage 属性。如果main类位于根包中,你也可以使用 @SpringBootApplication 注解。

下面是一个典型的结构:

com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
+- CustomerController.java

Application.java 文件将声明 main 方法,还有基本的 @Configuration 。

package com.example.myproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

配置类

  • Spring Boot提倡基于Java的配置。尽管你可以使用一个XML源来调用SpringApplication.run() ,我们通常建议你使用 @Configuration 类作为主要源。
  • 一般定义 main 方法的类也是主要 @Configuration 的一个很好候选。

注:很多使用XML配置的Spring配置示例已经被发布到网络上。你应该总是尽可能的使用基于Java的配置。搜索查看 enable* 注解就是一个好的开端。

导入其他配置类

  • 你不需要将所有的 @Configuration 放进一个单独的类。 @Import 注解可以用来导入其他配置类。
  • 另外,你也可以使用 @ComponentScan 注解自动收集所有的Spring组件,包括 @Configuration 类。

导入XML配置

  • 如果你绝对需要使用基于XML的配置,我们建议你仍旧从一个 @Configuration 类开始。
  • 你可以使用附加的 @ImportResource 注解加载XML配置文件。

自动配置

  • Spring Boot自动配置(auto-configuration)尝试根据你添加的jar依赖自动配置你的Spring应用。
  • 例如,如果你的classpath下存在 HSQLDB ,并且你没有手动配置任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库。
  • 你可以通过将 @EnableAutoConfiguration 或 @SpringBootApplication 注解添加到一个 @Configuration 类上来选择自动配置。

注:你只需要添加一个 @EnableAutoConfiguration 注解。我们建议你将它添加到主 @Configuration 类上。

逐步替换自动配置

  • 自动配置是非侵占性的,任何时候你都可以定义自己的配置类来替换自动配置的特定部分。例如,如果你添加自己的 DataSource bean,默认的内嵌数据库支持将不被考虑。
  • 如果需要找出当前应用了哪些自动配置及应用的原因,你可以使用 mvn spring-boot:run --debug 开关启动应用。这将会记录一个自动配置的报告并输出到控制台。
    (自己尝试的时候粗略的看了一下,并没有看到自动配置的报告)

禁用特定的自动配置

  • 如果发现应用了你不想要的特定自动配置类,你可以使用 @EnableAutoConfiguration 注解的排除属性来禁用它们。

      import org.springframework.boot.autoconfigure.*;
      import org.springframework.boot.autoconfigure.jdbc.*;
      import org.springframework.context.annotation.*;
      @Configuration
      @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
      public class MyConfiguration {
      }
    

Spring Beans和依赖注入

  • 你可以自由地使用任何标准的Spring框架技术去定义beans和它们注入的依赖。简单起见,我们经常使用 @ComponentScan 注解搜索beans,并结合 @Autowired 构造器注入。

  • 如果使用上面建议的结构组织代码(将应用类放到根包下),你可以添加 @ComponentScan 注解而不需要任何参数。你的所有应用程序组件( @Component , @Service , @Repository , @Controller 等)将被自动注册为Spring Beans。

  • 下面是一个 @Service Bean的示例,它使用构建器注入获取一个需要的 RiskAssessor bean。

    package com.example.service;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.stereotype.Service;
    @Service
    public class DatabaseAccountService implements AccountService {
              private final RiskAssessor riskAssessor;
      @Autowired
      public DatabaseAccountService(RiskAssessor riskAssessor) {
          this.riskAssessor = riskAssessor;
      }
    // ...
    }
    

注:注意如何使用构建器注入来允许 riskAssessor 字段被标记为 final ,这意味着 riskAssessor 后续是不能改变的。

使用@SpringBootApplication注解

  • 很多Spring Boot开发者总是使用 @Configuration , @EnableAutoConfiguration 和 @ComponentScan 注解他们的main类。由于这些注解被如此频繁地一块使用(特别是你遵循以上最佳实践时),Spring Boot提供一个方便的 @SpringBootApplication 选择。

  • 该 @SpringBootApplication 注解等价于以默认属性使用 @Configuration , @EnableAutoConfiguration 和 @ComponentScan 。

    package com.example.myproject;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication // same as @Configuration @EnableAutoConfiguration      @ComponentScan
    public class Application {
      public static void main(String[] args) {
          SpringApplication.run(Application.class, args);
      }
    }
    

运行应用程序

  • 将应用打包成jar并使用一个内嵌HTTP服务器的一个最大好处是,你可以像其他方式那样运行你的应用程序。调试SpringBoot应用也很简单;你不需要任何特殊IDE或扩展。

注:本章节只覆盖基于jar的打包,如果选择将应用打包成war文件,你最好参考一下服务器和IDE文档。

从IDE中运行

  • 你可以从IDE中运行Spring Boot应用,就像一个简单的Java应用,但是,你首先需要导入项目。导入步骤跟你的IDE和构建系统有关。大多数IDEs能够直接导入Maven项目,例如Eclipse用户可以选择 File 菜单的 Import… --> Existing Maven Projects 。

  • 如果不能直接将项目导入IDE,你可以需要使用构建系统生成IDE元数据。Maven有针对Eclipse和IDEA的插件;Gradle为各种IDEs提供插件。

注:如果意外地运行一个web应用两次,你将看到一个"端口已在使用中"错误。为了确保任何存在的实例是关闭的,STS用户可以使用 Relaunch 按钮而不是 Run 按钮。

作为一个打包后的应用运行

  • 如果使用Spring Boot Maven或Gradle插件创建一个可执行jar,你可以使用 java -jar 运行你的应用。例如:

    $ java -jar target/myproject-0.0.1-SNAPSHOT.jar
    
  • 运行一个打包的程序并开启远程调试支持是可能的,这允许你将调试器附加到打包的应用程序上:

    $ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \-jar target/myproject-0.0.1-SNAPSHOT.jar
    

使用Maven插件运行

  • Spring Boot Maven插件包含一个 run 目标,它可以用来快速编译和运行应用程序。应用程序以一种暴露的方式运行,由于即时"热"加载,你可以编辑资源。

    $ mvn spring-boot:run
    

你可能想使用有用的操作系统环境变量:

  $ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M

使用Gradle插件运行

  • Spring Boot Gradle插件也包含一个 run 目标,它可以用来以暴露的方式运行你的应用程序。不管你什么时候导入 springboot-plugin ,bootRun 任务总是被添加进去。

    $ gradle bootRun
    

你可能想使用那些有用的操作系统环境变量:
$ $ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M

热交换

  • 由于Spring Boot应用程序只是普通的Java应用,那JVM热交换(hot-swapping)应该能出色的工作。JVM热交换在它能替换的字节码上有些限制,更全面的解决方案可以使用Spring Loaded项目或JRebel。

打包用于生产的应用程序

  • 可执行jars可用于生产部署。由于它们是自包含的,非常适合基于云的部署。关于其他“生产准备”的特性,比如健康监控,审计和指标REST,或JMX端点,可以考虑添加 spring-boot-actuator 。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容