Spring boot 2 . 参考手册(Part II部分)

11.3.1 @RestController and @RequestMapping 注解

@RestController 是一个stereotyp(原型)注解, 用于提供给用户和Spring阅读 .
@RequestMapping 注解 ,提供URL访问的路由信息.
这两个注解都是Spring MVC提供的 .

11.3.2 @EnableAutoConfiguration 注解

这个注解告诉Spring boot 推测spring的配置方式 .

11.5 创建一个能够运行的jar包

为了让应用成为一个自包含的包. 需要pom.xml中包含以下插件:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

构建系统

选maven或者gradle

依赖管理

每一个版本的Spring boot 版本都定义了所引用的Spring Framework的版本 , 所以 , 最好不要自己再去定义Spring Framework的版本号了.

13.2 Maven

spring-boot-starter-parent包含以下特性:
- java 1.8 作为默认的编译版本
- UTF-8 编码
- 依赖管理单元可以让我们忽略一些通用依赖的版本号 .
- 自动检测的resource过滤
- 自动检测的插件配置
- 自动检测application.properties, application.yml(包括profile , 例如 application-foo.properties , application-foo.yml)

13.2.1 继承starter parent

<!-- Inherit defaults from Spring Boot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.BUILD-SNAPSHOT</version>
</parent>

这个部分 , 只需要修改version. 如果引用了其它的starter , 不需要单独声明version.

13.2.2 没有parent pom的情况下使用spring boot

?没懂
如果不想使用parent , 我们任然可以使用依赖管理的功能(不包含插件管理). 这个功能通过添加scope=import实现:

<dependencyManagement>
     <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.0.0.BUILD-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

13.2.3 使用spring boot maven plugin

提供打包功能

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

13.5 starters

14组织代码

14.1 不推荐使用默认包

推荐使用反向域名命名包

14.2 定位main application class

推荐的文件结构

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

标准配置java类:

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);
    }

}

15 配置类

一般推荐使用@Configuration 类. main函数定义的地方就是配置@configuration的地方. 很多地方可能使用XML文件进行配置 ,但是最好使用java类来配置 . 查找Enable* .

15.1 导入额外的配置类 ?

不需要将所所有的配置都放在一个@Configuration类中 . @Import注解可以用来注入更多的配置 . 另一种方法是使用@ComponentScan来自动扫描所有的组件 . 包括@Configuration

15.2 导入XML配置文件 ?

如果实在要使用XML文件, 依然推荐使用@Configuration 类 ,然后通过@ImportResource 注解来加载XML配置文件.

16 自动配置

spring boot 会根据导入的jar依赖来自动配置 . 比如HSQLDB没有在类上, 而且没有显式的配置其它的数据源 . 那么就会默认使用内存数据库. 这个功能需要使用@EnableAutoConfiguration 或者 @SpringBootApplication注解在一个@Configuration类上面来启用.
只能添加一个@EnableAutoConfiguration.

16.1 逐步替换 auto-configuration

自动配置是非侵入式的(noninvasive), 所以可以在任何时候替换成自己定义的内容 . 如果需要看到详情, 在运行的时候打开–debug选项 .

16.2 禁用特定的auto-configuration

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

如果类不在classpath上的话 , 可以使用excludeName属性来排除.

17 spring beans 以及依赖注入(DI)

我们常使用@ComponentScan来查找beans , 加上@Autowired 的构造器注入, 配合的很好 . 如果将@ComponentScan注解的类放在包结构的root上. 应用中的所有组件 @Component @Service @Repository @Controller等都会自动注册成Spring的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;
    }

    // ...

}

如果bean只有一个构造方法 , 可以忽略@Autowried

@Service
public class DatabaseAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    public DatabaseAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}

18 使用 @SpringBootApplication 注解

@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

19 运行程序

  • 从IDE运行
  • 通过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
  • 使用mvn plugin
mvn spring-boot:run
  • 使用gradle plugin
gradle bootRun
  • 热切换
    看第二十章

20 开发工具(restart liveReload) ?

spring-boot-devtools可以被引用到任何开发阶段的工程引入开发时特性.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

这个功能在以java -jar方式运行时 , 自动被禁用.

20.1 属性默认值

有一些库使用缓存来改善性能 . 在生产环境中 , 缓存是十分有用的 .但是在开发的时候 , 这些性能是不需要的. spring-boot-devtools 会禁止掉这些特性. 缓存选项一班可以通过application.properties文件来设置 .
详细缓存列表见链接 : https://github.com/spring-projects/spring-boot/tree/master/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java

20.2 自动重启

使用spring-boot-devtools的工程 , 在文件发生改变的时候会自动重启. 注意一些静态文件, 不需要重启应用.

20.2.1 excluding resources

/META-INF/maven, /META-INF/resources ,/resources ,/static ,/public or /templates,目录下的文件不会触发重启, 而是reload.

21 打包生产环境应用

查看第五章的spring-boot-actuator

PART IV. Spring boot features

23 SpringApplication

SpringApplication类提供快捷方便的方式启动main().

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

23.1 启动失败

spring boot 提供了大量的FailureAnalyzer的实现 ,我们可以自行添加(后文介绍)

java -jar myproject-0.0.1-SNAPSHOT.jar --debug

23.2 自定义启动的Banner

spring:
    main:
        banner-mode: "off"

23.3 自定义SpringApplication

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}

也可以使用application.properties文件配置SpringApplication , 详见C24.

23.4 Fluent builder API ?

23.5 Application 事件和监听器

除了Spring Framework的事件 , 例如 ContextRefreshedEvent , SpringApplication也可以发送一些其它类型的事件 .
一些事件在ApplicationContext创建之前就被触发了,因此并不能使用@Bean. 这些事件可以使用SpringApplication.addListeners()或者 SpringApplicationBuilder.listeners()方法.
如果需要这些监听器不管以何种方式启动application都注册 , 那么可以添加一个META-INF/spring.factories文件. 引用需要的监听器 :

org.springframework.context.ApplicationListener=com.example.project.MyListener

应用的事件传播顺序如下:
1. ApplicationStartingEvent 在run开始的时候 , 在监听器和初始化器注册之后.
2. ApplicationEnvironmentPreparedEvent 在context中Environment已经知道的时候 , 但是在context创建之前
3. ApplicationPreparedEvent 在refresh之前, 在所有bean定义加载之后
4. ApplicationReadyEvent 在refresh和任何相关的表示应用已经可以接受请求的回调执行完之后
5. ApplicationFailedEvent 在应用启动的时候发生异常的时候

23.6 Web environment

SpringApplication 会尝试使用正确的ApplicationContext . 默认的AnnotationConfigApplicationContext或者 AnnotationConfigServletWerServerApplicationContext会被使用. 这取决于我们是否是在开发一个web应用.

23.7 使用应用的参数

如果想使用传递给SpringApplication.run()的参数 . 可以注入一个ApplicationArguments bean . 这个类的接口提供了args 还有 转化过得options和非options .

import org.springframework.boot.*
import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*

@Component
public class MyBean {

    @Autowired
    public MyBean(ApplicationArguments args) {
        boolean debug = args.containsOption("debug");
        List<String> files = args.getNonOptionArgs();
        // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
    }

}

23.8 使用ApplicationRunner 或者 CommandLineRunner

如果现在SpringApplication启动时候做一些操作的话, 可以实现ApplicationRunner或者CommandLineRunner接口. 如果有多个要按顺序执行的话, 再实现org.springframework.core.Ordered就可以了

import org.springframework.boot.*
import org.springframework.stereotype.*

@Component
public class MyBean implements CommandLineRunner {

    public void run(String... args) {
        // Do something...
    }

}

23.9 应用退出

可以实现org.springframework.boot.ExitCodeGenerator 在应用退出的时候实现逻辑

23.10 admin功能

通过设置spring.application.admin.enabled 属性 ,会暴露出一些对应用进行管理的接口

24 外部化的配置

外部化配置用以实现部署同样的代码到不同环境. 可以使用的外部配置文件包括: properties文件 , YAML文件 , 环境变量 , 命令行参数 . 属性可以通过@Value注解直接注入到bean中(通过Spring 的Environment抽象或者@ConfigurationProperties注解的结构化对象). Spring boot使用了一个特定的顺序加载配置 , 这样后面的配置就会自动发现并且覆盖之前的配置 . 顺序如下:
1. devtools 在根目录上全局设定的properties(~/.spring-boot-devtools.properties 如果devtools被激活)
2. @TestPropertySource test中注解
3. @SpringBootTest#properties test中注解的属性
4. 命令行的属性
5. SPRING_APPLICATION_JSON(内嵌在环境变量中或者系统属性中)
6. ServletConfig 初始化参数
7. ServletContext 初始化参数
8. JNDI 用java:comp/env中的属性
9. Java 系统属性(System.getProperties())
10. 操作系统环境变量
11. RandomValuePropertySource 只有random.*
12. jar 包外面的 application-{profile}.properties 和YAML
13. jar 包里面的 application-{profile}.properties 和YAML
14. @PropertySource 注解的@Configuration 类
15. 默认属性(用SpringApplication.setDefaultProperties声明的属性)

24.1 配置随机值

RandomValuePropertySource 可以用于注入随机值.

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

24.2 使用command line 属性值

SpringApplication会将 “–server.port=9000” 这样的命令行的值转换成属性并且加入到Spring的Environment中 . 如果不想它们被加入到Envrionment中 ,如下

SpringApplication.setAddCommandLineProperties(false)

24.3 应用的属性文件 TBC

以下几个位置的application.properties文件会被加入到Environment中
1. 当前文件夹的/config子文件夹
2. 当前文件夹
3. classpath的/config文件夹
4. classpath本身

更高级的目录覆盖低级目录

java -jar myproject.jar --spring.config.name=myproject
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

24.4 特定profile的属性

application-{profile}.properties 用以声明特定profile的属性. 如果没有特定的激活的profile , 自动加载application-default.properties .

24.5 属性中的占位符

后面的属性定义可使用前面声明的值

app.name=MyApp
app.description=${app.name} is a Spring Boot application

24.6 使用YAML代替属性值

如果使用了starters , SnakeYAML功能自动引入 . 不需要添加maven

24.6.1 加载YAML

有两个类可以用来加载YAML文件. YamlPropertiesFactoryBean 将YAML加载成Properties . YamlMapFactoryBean 将YAML加载成Map.

environments:
    dev:
        url: http://dev.bar.com
        name: Developer Setup
    prod:
        url: http://foo.bar.com
        name: My Cool App
my:
   servers:
       - dev.bar.com
       - foo.bar.com

被转化成:

environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

24.6.2 把YAML属性当做Spring Environment使用

YamlPropertySourceLoader 可以将YAML转变成PropertySource 并且放在Spring Environment中. 这样我们就可以使用@Value注解和占位符来获取YAML的属性.

24.6.3 多profile YAML文件

server:
    address: 192.168.1.100
---
spring:
    profiles: development
server:
    address: 127.0.0.1
---
spring:
    profiles: production
server:
    address: 192.168.1.120

24.6.4 YAML缺点

不能通过@PropertySource注解加载上去 . 所以需要加载的话一定要使用properties文件.

24.6.5 合并YAML 列表 TBC

24.7 类型安全的属性配置 TBC

25 profiles TBC

@Configuration
@Profile("production")
public class ProductionConfiguration {

    // ...

}

一般的方法是在环境属性中声明 spring.profiles.active=dev,hsqldb
也可以在命令行中使用参数:

--spring.profiles.active=dev,hsqldb

25.1 添加active profiles

26 日志 TBC

26.1 日志格式

26.2 控制台输出

java -jar myapp.jar --debug

或者直接在application.properties中指定debug=true

26.3 输出日志到文件

设置logging.file属性或者logging.path属性 . 否则日志只会在控制台输出.

26.4 日志级别

logging.level.*=LEVEL (TRACE/DEBUG/INFO/WARN/ERROR/FATAL/OFF)

logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

26.5 自定义日志配置

可以使用logging.config指定日志配置文件的位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值