其他的功能支持-1
Profiles
Spring配置文件提供了一种分离应用程序配置部分的方法,使其仅在特定环境中可用。任何@Component、@Configuration或@ConfigurationProperties都可以标记为@Profile,以限制加载时的限制,如下例所示:
@Configuration(proxyBeanMethods = false) @Profile("production") public class ProductionConfiguration { // ... }
如果@ConfigurationProperties bean是通过@EnableConfigurationProperties而不是自动扫描注册的,则需要在具有@EnableConfigurationProperties注释的@Configuration类上指定@Profile注释。在扫描@ConfigurationProperties的情况下,可以在@ConfigurationProperties类本身上指定@Profile。
你可以使用spring.profiles.active属性指定哪些配置文件处于活动状态。例如,你可以在application.properties这样写:
@Configuration(proxyBeanMethods = false) @Profile("production") public class ProductionConfiguration { // ... }
也可以使用以下开关在命令行中指定它:–spring.profiles.active=dev,hsqldb
国际化
springboot支持本地化消息,因此你的应用程序可以满足不同语言偏好的用户。默认情况下,springboot在类路径的根目录下查找是否存在消息资源包。
当配置的资源包的默认属性文件可用时(默认是messages.properties),则会自动配置。如果资源包仅包含特定于语言的属性文件,则需要添加默认文件。如果找不到与任何配置的基名称匹配的属性文件,则不会有自动配置的MessageSource。
spring.messages.basename=messages,config.i18n.messages spring.messages.fallback-to-system-locale=false
spring.messages.basename支持逗号分隔的位置列表,可以是包限定符,也可以是从类路径根解析的资源。
有关更多受支持的选项,请参阅MessageSourceProperties。
JSON
SpringBoot提供了三个JSON引导库集成:
- Gson
- Jackson
- JSON-B
Jackson是首选的默认库。
Jackson
提供了Jackson的自动配置,Jackson是spring-boot-starter-json的一部分。当Jackson在类路径上时,会自动配置ObjectMapper bean。SpringBoot提供了几个配置属性来定制ObjectMapper的配置。
Gson
提供Gson的自动配置。当Gson位于类路径上时,会自动配置Gson bean。几个spring.gson.*配置属性用于自定义配置。为了获得更多的控制权,可以使用一个或多个GsonBuilderCustomizer bean。
JSON-B
提供JSON-B的自动配置。当JSON-B和一个实现在类路径上时,Jsonb bean将被自动配置。首选的JSON-B实现是Apache Johnzon,它提供了依赖关系管理。
优雅关闭
所有四个嵌入式web服务器(Jetty、Reactor Netty、Tomcat和Undertow)以及反应式和基于Servlet的web应用程序都支持优雅关闭。它是关闭应用程序上下文的一部分,在停止SmartLifecycleBeans的最早阶段执行。此停止处理使用一个超时,该超时提供了一个宽限期,在此期间允许完成现有请求,但不允许新请求。不允许新请求的确切方式因所使用的web服务器而异。Jetty、Reactor Netty和Tomcat将停止在网络层接受请求。Undertow将接受请求,但会立即响应“服务不可用”(503)响应。
Tomcat的优雅关闭需要Tomcat 9.0.33或更高版本。
要启用正常关闭,请配置服务器关闭属性,如下例所示:
server.shutdown=graceful
要配置超时时间,请配置spring.lifecycle.timeout-per-shutdown-phase属性,如下例所示:
spring.lifecycle.timeout-per-shutdown-phase
RSocket
RSocket是一种用于字节流传输的二进制协议。它通过在单个连接上传递异步消息来启用对称交互模型。
spring框架的spring-messaging模块在客户端和服务器端为RSocket请求者和响应者提供支持。
RSocket策略自动配置
SpringBoot自动配置一个RSocketStrategies bean,该bean提供编码和解码RSocket有效负载所需的所有基础设施。默认情况下,自动配置将尝试配置以下内容(按顺序):
- Jackson的CBOR编解码器
- Jackson的JSON编解码器
开发人员可以通过创建实现RSocketStrategiesCustomizer接口的bean来定制RSocketStrategies组件。注意,它们的@Order很重要,因为它决定了编解码器的顺序
RSocket服务器自动配置
springboot提供RSocket服务器自动配置。所需的依赖关系由 spring-boot-starter-rsocket提供。
springboot允许从WebFlux服务器或独立的RSocket服务器在WebSocket上公开RSocket。这取决于应用程序的类型及其配置。
对于WebFlux应用程序(即WebApplicationType.REACTIVE),则仅当以下属性匹配时,RSocket服务器才会插入Web服务器:
spring.rsocket.server.mapping-path=/rsocket # a mapping path is defined spring.rsocket.server.transport=websocket # websocket is chosen as a transport #spring.rsocket.server.port= # no port is defined
只有Reactor Netty支持将RSocket插入web服务器,因为RSocket本身就是用这个库构建的。
RSocket TCP或websocket服务器作为独立的嵌入式服务器启动。除了依赖性要求外,唯一需要的配置是为该服务器定义一个端口:
spring.rsocket.server.port=9898 # the only required configuration spring.rsocket.server.transport=tcp # you\'re free to configure other properties
Spring消息传递RSocket支持
SpringBoot将为RSocket自动配置Spring消息传递基础设施。
这意味着Spring Boot将创建一个RSocketMessageHandler bean来处理对应用程序的RSocket请求。
使用RSocketRequester调用RSocket服务
一旦在服务器和客户机之间建立了RSocket通道,任何一方都可以向另一方发送或接收请求。
对于服务器,你可以在RSocket @Controller的任何处理程序方法上注入RSocketRequester实例。作为客户机,你需要首先配置并建立RSocket连接。弹簧引导自动配置RSocketRequest.Builder对于这种情况下使用预期的编解码器。
这个RSocketRequest.Builder实例是一个原型bean,这意味着每个注入点都将为你提供一个新实例。这是有意的,因为这个构建器是有状态的,你不应该使用同一个实例创建具有不同设置的请求者。
以下代码显示了一个典型示例:
@Service public class MyService { private final Mono<RSocketRequester> rsocketRequester; public MyService(RSocketRequester.Builder rsocketRequesterBuilder) { this.rsocketRequester = rsocketRequesterBuilder .connectTcp("example.org", 9898).cache(); } public Mono<User> someRSocketCall(String name) { return this.rsocketRequester.flatMap(req -> req.route("user").data(name).retrieveMono(User.class)); } }
使用RestTemplate调用REST服务
如果需要从应用程序调用远程REST服务,可以使用Spring框架的RestTemplate 类。由于RestTemplate 实例通常需要在使用之前进行定制,SpringBoot不提供任何一个自动配置的RestTemplate bean。但是,它会自动配置RestTemplateBuilder,它可以在需要时用于创建RestTemplate实例。自动配置的RestTemplateBuilder确保将敏感的HttpMessageConverters 应用于由于RestTemplate实例。
以下代码显示了一个典型示例:
@Service public class MyService { private final RestTemplate restTemplate; public MyService(RestTemplateBuilder restTemplateBuilder) { this.restTemplate = restTemplateBuilder.build(); } public Details someRestCall(String name) { return this.restTemplate.getForObject("/{name}/details", Details.class, name); } }
RestTemplateBuilder 包含许多有用的方法,可用于快速配置RestTemplate。例如,要添加基本身份验证支持,可以使用builder.basicAuthentication(“user”, “password”).build()。
RestTemplate 自定义
RestTemplate定制有三种主要方法,这取决于你希望自定义应用的范围。
要使任何自定义的范围尽可能窄,请插入自动配置的RestTemplateBuilder,然后根据需要调用其方法。每个方法调用都会返回一个新的RestTemplateBuilder 实例,因此定制只影响生成器的这种使用。
要在应用程序范围内进行附加定制,请使用RestTemplateCustomizer bean。所有这样的bean都会自动注册到自动配置的RestTemplateBuilder中,并应用于使用它构建的任何模板。
以下示例显示了一个自定义项,该自定义项为除192.168.0.5之外的所有主机配置代理的使用:
static class ProxyCustomizer implements RestTemplateCustomizer { @Override public void customize(RestTemplate restTemplate) { HttpHost proxy = new HttpHost("proxy.example.com"); HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(new DefaultProxyRoutePlanner(proxy) { @Override public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context) throws HttpException { if (target.getHostName().equals("192.168.0.5")) { return null; } return super.determineProxy(target, request, context); } }).build(); restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient)); } }
最后,很少使用的选项是创建你自己的RestTemplateBuilder bean。这样做会关闭RestTemplateBuilder 的自动配置,并防止使用任何RestTemplateCustomizer bean。
使用WebClient调用REST服务
如果类路径上有Spring WebFlux,还可以选择使用WebClient调用远程REST服务。与RestTemplate相比,此客户端具有更高的功能性,
SpringBo为你创建并预配置WebClient.Builder,强烈建议将其注入组件中,并使用它创建WebClient实例。springboot正在配置该构建器以共享HTTP资源、以与服务器相同的方式反映编解码器的设置。
以下代码显示了一个典型示例:
@Service public class MyService { private final WebClient webClient; public MyService(WebClient.Builder webClientBuilder) { this.webClient = webClientBuilder.baseUrl("https://example.org").build(); } public Mono<Details> someRestCall(String name) { return this.webClient.get().uri("/{name}/details", name) .retrieve().bodyToMono(Details.class); } }
WebClient 运行
SpringBoot将根据应用程序类路径上可用的库自动检测哪个ClientHttpConnector来驱动WebClient。目前,Reactor Netty和Jetty的客户端是受支持的。
spring-boot-starter-webflux依赖于io.projectreactor.netty:reactor-netty。默认情况下,它同时提供服务器和客户端实现。如果你选择使用Jetty作为反应式服务器,你应该添加对Jetty反应式HTTP客户端库的依赖性org.eclipse.jetty:jetty-reactive-httpclient。对服务器和客户端使用相同的技术有其优点,因为它将自动在客户端和服务器之间共享HTTP资源。
开发人员可以通过提供一个自定义的ReactorResourceFactory 或JettyResourceFactory bean来覆盖Jetty和Reactor Netty的资源配置-这将应用于客户机和服务器。
如果你希望覆盖客户机的选择,那么你可以定义自己的ClientHttpConnector bean并完全控制客户机配置。
WebClient 自定义
WebClient定制有三种主要方法,这取决于你希望自定义应用的范围。
要使任何自定义的范围尽可能窄,请插入自动配置的WebClient.Builder然后根据需要调用它的方法。
WebClient.Builder实例是有状态的:生成器上的任何更改都会反映在随后使用它创建的所有客户端中。如果要使用同一生成器创建多个客户端,还可以考虑使用克隆生成器WebClient.Builder other = builder.clone();对所有应用程序进行附加定制WebClient.Builder实例中,可以声明WebClientCustomizer bean并更改WebClient.Builder局部注射。最后,你可以返回到原始API并使用WebClient.create(). 在这种情况下,不会应用自动配置或WebClientCustomizer。
Validation
只要JSR-303实现(比如Hibernate验证器)在类路径上,Bean validation 1.1支持的方法验证特性就会自动启用。用这个bean注释方法javax.验证参数和/或返回值的约束。具有这种带注释方法的目标类需要在类型级别用@Validated注释进行注释,以便在其方法中搜索内联约束注释。
例如,以下服务将触发对第一个参数的验证,确保其大小在8到10之间:
@Service @Validated public class MyBean { public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code, Author author) { ... } }
发送邮件
Spring框架为使用JavaMailSender接口发送电子邮件提供了一个抽象,SpringBoot为它提供了自动配置以及一个启动模块。
如果spring.mail.host相关的库(由 spring-boot-starter-mail定义)是可用的,如果不存在,则创建一个默认的JavaMailSender。这个Sender中的配置项可以进一步自定义spring.mail命名空间。有关更多的信息,请查看MailProperties 。
特别是,某些默认超时值是无限的,你可能需要更改该值,以避免线程被无响应的邮件服务器阻塞,如下例所示:
spring.mail.properties.mail.smtp.connectiontimeout=5000 spring.mail.properties.mail.smtp.timeout=3000 spring.mail.properties.mail.smtp.writetimeout=5000
还可以使用JNDI中的现有会话配置JavaMailSender:
spring.mail.jndi-name=mail/Session
设置jndi名称时,它优先于所有其他与会话相关的设置。
Hazelcast
如果Hazelcast在类路径上并且找到了合适的配置,那么SpringBoot会自动配置一个Hazelcast实例,你可以将其注入到应用程序中。
如果你定义一个com.hazelcast.config.Config bean,springboot使用它。如果你的配置定义了一个实例名,SpringBoot将尝试定位一个现有实例,而不是创建一个新实例。
还可以通过配置指定要使用的Hazelcast配置文件,如以下示例所示:
spring.hazelcast.config=classpath:config/my-hazelcast.xml
否则,Spring Boot会尝试从默认位置查找Hazelcast配置:在工作目录或类路径的根目录中的hazelcast.xml,或与.yaml文件在同一个位置。我们还检查hazelcast.config系统属性已设置。
如果类路径上存在hazelcast-client,Spring Boot首先通过检查以下配置选项来尝试创建client:
- 存在一个com.hazelcast.client.config.ClientConfig bean
- 由配置文件定义spring.hazelcast.config属性
- 存在hazelcast.client.config系统属性。
- hazelcast-client.xml在工作目录或类路径的根目录下。
- hazelcast-client.yaml在工作目录或类路径的根目录下。
SpringBoot还为Hazelcast提供了显式缓存支持。如果启用了缓存,HazelcastInstance将自动包装在CacheManager实现中。
Quartz 调度器
SpringBoot为使用Quartz调度程序提供了一些便利,包括spring-boot-starter-quartz启动器。如果Quartz可用,则自动配置调度程序(通过SchedulerFactoryBean抽象)。
以下类型的bean将自动拾取并与调度程序关联:
- JobDetail:定义一个特定的作业。JobDetail实例可以使用JobBuilder API构建。
- Calendar
- 触发器:定义触发特定作业的时间。
默认情况下,使用内存中的JobStore。但是,如果应用程序中有数据源bean,并且spring.quartz.job-store-type属性被配置,如下例所示:
spring.quartz.job-store-type=jdbc
使用JDBC存储时,可以在启动时初始化,如下例所示:
spring.quartz.jdbc.initialize-schema=always
默认情况下,使用Quartz库提供的标准脚本检测和初始化数据库。这些脚本删除现有的表,在每次重新启动时删除所有触发器。也可以通过设置spring.quartz.jdbc.schema属性。
要让Quartz使用应用程序主数据源以外的数据源,请声明一个DataSource bean,用@QuartzDataSource注释它的@bean方法。这样做可以确保SchedulerFactoryBean和模式初始化都使用特定于Quartz的数据源。
默认情况下,配置创建的作业不会覆盖已从永久作业存储区读取的已注册作业。要启用覆盖现有作业定义,请设置spring.quartz.overwrite-existing-jobs属性。
特别是,Executor bean与调度器没有关联,因为Quartz提供了一种通过spring.quartz.properties. 如果需要自定义任务执行器,请考虑实现SchedulerFactoryBeanCustomizer。
作业可以定义setter来注入数据映射属性。普通bean也可以以类似的方式注入,如下例所示:
public class SampleJob extends QuartzJobBean { private MyService myService; private String name; // Inject "MyService" bean public void setMyService(MyService myService) { ... } // Inject the "name" job data property public void setName(String name) { ... } @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { ... } }
任务执行和调度
在上下文中没有Executor bean的情况下,SpringBoot自动配置一个ThreadPoolTaskExecutor,默认可以自动与异步任务执行(@enablesync)和SpringMVC异步请求处理相关联。
如果你在上下文中定义了一个自定义执行器,那么常规任务执行(即@EnableAsync)将透明地使用它,但是 Spring MVC支持将不会被配置,因为它需要一个AsyncTaskExecutor实现(名为applicationTaskExecutor)。根据你的目标安排,你可以将你的Executor更改为ThreadPoolTaskExecutor,或者同时定义一个ThreadPoolTaskExecutor和一个封装自定义执行器的AsyncConfigurer。
自动配置的TaskExecutorBuilder允许你轻松创建实例,以重现自动配置在默认情况下的功能。
线程池使用8个核心线程,它们可以根据负载增长和收缩。这些默认设置可以使用spring.task.execution命名空间,如下例所示:
spring.task.execution.pool.max-size=16 spring.task.execution.pool.queue-capacity=100 spring.task.execution.pool.keep-alive=10s
这会将线程池更改为使用有界队列,以便当队列已满(100个任务)时,线程池将增加到最多16个线程。当线程空闲10秒(而不是默认的60秒)时,会回收线程池,因此池的收缩更具攻击性。
如果需要与计划的任务执行关联(@EnableScheduling),也可以自动配置ThreadPoolTaskScheduler。线程池默认使用一个线程,可以使用spring.task.scheduling命名空间。
如果需要创建自定义的执行器或调度器,那么TaskExecutorBuilder bean和TaskSchedulerBuilder bean都可以在上下文中使用。
Spring集成
SpringBoot为使用Spring Integration提供了一些便利,包括 spring-boot-starter-integration启动器。Spring Integration提供了对消息传递和其他传输(如HTTP、TCP等)的抽象。如果Spring Integration在你的类路径上可用,它将通过@EnableIntegration 注释初始化。
SpringBoot还配置了一些由附加的Spring Integration模块触发的特性。如果spring-integration-jmx也在类路径上,那么消息处理统计信息将通过jmx发布。如果spring-integration-jdbc可用,则可以在启动时创建默认数据库模式,如下所示:
spring.integration.jdbc.initialize-schema=always
如果spring-integration-rsocket 是可用的,开发人员可以使用spring.rsocket.server.*属性来配置RSocket服务器,并允许它使用IntegrationRSocketEndpoint或RSocketOutboundGateway组件来处理传入的RSocket消息。这个基础设施可以处理Spring集成RSocket通道适配器和@MessageMapping处理程序(spring.integration.rsocket.server.message-mapping-enabled已被配置)。
Spring Boot还可以使用配置属性自动配置ClientRSocketConnector:
# Connecting to a RSocket server over TCP spring.integration.rsocket.client.host=example.org spring.integration.rsocket.client.port=9898 # Connecting to a RSocket Server over WebSocket spring.integration.rsocket.client.uri=ws://example.org
有关详细信息,请参阅IntegrationAutoConfiguration和IntegrationProperties类。
默认情况下,如果存在一个Micrometer meterRegistry bean, Spring Integration metrics将由Micrometer管理。如果你希望使用遗留的Spring集成度量,请将DefaultMetricsFactory bean添加到应用程序上下文中。
Spring Session
SpringBoot为各种数据存储提供Spring会话自动配置。在构建Servlet web应用程序时,可以自动配置以下存储:
-
JDBC
-
Redis
-
Hazelcast
-
MongoDB
构建反应式web应用程序时,可以自动配置以下存储:
-
Redis
-
MongoDB
如果类路径上存在一个Spring Session模块,SpringBoot会自动使用该存储实现。如果有多个实现,则必须选择要用于存储会话的存储类型。例如,要使用JDBC作为后端存储,可以按如下方式配置应用程序:
spring.session.store-type=jdbc
你可以通过将store type设置为none来禁用Spring会话。
每个Store都有特定的附加设置。例如,可以自定义JDBC存储的表名,如下例所示:
spring.session.jdbc.table-name=SESSIONS
要设置会话的超时,可以使用spring.session.timeout属性。如果未设置该属性,则自动配置将返回到的值server.servlet.session.timeout。
监控和管理JMX
Java管理扩展(javamanagementextensions,JMX)提供了监视和管理应用程序的标准机制。Spring Boot将最适合的MBeanServer公开为一个ID为MBeanServer的bean。任何用Spring JMX 注解(@ManagedResource, @ManagedAttribute, 或@ManagedOperation)的bean都会暴露给它。
如果你的平台提供了一个标准的MBeanServer,Spring Boot将使用它,并在必要时默认为 VM MBeanServer。如果所有这些都失败了,将创建一个新的MBeanServer。
有关更多详细信息,请参阅JmxAutoConfiguration类。
WebSockets
Web Services
Kotlin支持
Kotlin是一种面向JVM(和其他平台)的静态类型语言,它允许编写简洁优雅的代码,同时提供与用Java编写的现有库的互操作性。
SpringBoot通过利用Spring框架、Spring数据和Reactor等其他Spring项目的支持来提供Kotlin支持。
要求
Spring Boot支持Kotlin 1.3.x。为了使用Kotlin,org.jetbrains.kotlin:kotlin-stdlib 和 org.jetbrains.kotlin:kotlin-reflect必须出现在类路径上。也可以使用kotlin-stdlib变体kotlin-stdlib-jdk7 和 kotlin-stdlib-jdk8。
由于Kotlin类在默认情况下是final的,所以您可能希望配置Kotlin spring插件,以便自动打开spring注释的类,以便可以代理它们。
在Kotlin中,序列化/反序列化JSON数据需要Jackson的Kotlin模块。当在类路径上找到它时,它会自动注册。如果Jackson和Kotlin存在,但Jackson Kotlin模块不存在,则会记录一条警告消息。
Null-safety
Kotlin的一个关键特性是null-safety。它在编译时处理空值,而不是将问题推迟到运行时并遇到NullPointerException。这有助于消除常见的bug源,而无需支付像Optional这样的包装器的成本。Kotlin还允许使用具有可空值的函数构造。
构建容器映像
通过将springboot应用程序打包到Docker映像中,或者使用Buildpacks创建可以在任何地方运行的Docker兼容容器映像,可以将它们容器化。
构建Docker映像
一个典型的SpringBoot fat jar可以通过在Dockerfile中添加几行代码来转换成Docker映像,Dockerfile可以用来构建镜像。但是,复制和运行docker映像中的fat jar有很多缺点。当运行一个fat jar而不进行解包时,总是会有一定的开销,在一个容器化的环境中,这一点很明显。另一个问题是,将应用程序的代码及其所有依赖项放在Docker映像的一个层中是次优的。由于重新编译代码的次数可能比升级所使用的SpringBoot版本的次数要多,所以最好将代码分开一点。如果将jar文件放在应用程序类之前的层中,Docker通常只需要更改最底层,就可以从缓存中获取其他文件。
分层Docker镜像
为了更容易地创建可以用dockerfile构建的优化Docker映像,SpringBoot支持向jar添加一个层索引文件。它提供了一个层的列表以及应该包含在这些层中的jar部分。索引中的层列表是根据层添加到Docker/OCI映像的顺序排序的。开箱即用,支持以下层:
- dependencies:常规发布的依赖项
- spring-boot-loader:对于org/springframework/boot/loader下的所有内容
- snapshot-dependencies:快照依赖项
- application:应用程序类和资源
下面显示了一个layers.id文件:
- "dependencies": - BOOT-INF/lib/library1.jar - BOOT-INF/lib/library2.jar - "spring-boot-loader": - org/springframework/boot/loader/JarLauncher.class - org/springframework/boot/loader/jar/JarEntry.class - "snapshot-dependencies": - BOOT-INF/lib/library3-SNAPSHOT.jar - "application": - META-INF/MANIFEST.MF - BOOT-INF/classes/a/b/C.class
这种分层是为了根据代码在应用程序构建之间更改的可能性而设计的。库代码不太可能在构建之间更改,因此它被放在自己的层中,以允许工具重用缓存中的层。应用程序代码更可能在构建之间更改,因此它被隔离在一个单独的层中。
创建Dockerfile
当你创建一个包含layers索引文件的jar时,spring-boot-jarmode-layertools jar将作为一个依赖项添加到jar中。在类路径上有了这个jar,你可以以一种特殊的模式启动应用程序,这种模式允许引导代码运行与应用程序完全不同的东西,例如,提取层的东西。以下是如何使用layertools jar模式启动jar:
$ java -Djarmode=layertools -jar my-app.jar
这将提供以下输出:
Usage: java -Djarmode=layertools -jar my-app.jar Available commands: list List layers from the jar that can be extracted extract Extracts layers from the jar for image creation help Help about any command
extract命令可用于轻松地将应用程序拆分为要添加到dockerfile中的层。下面是一个使用jarmode的Dockerfile示例。
FROM adoptopenjdk:11-jre-hotspot as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract FROM adoptopenjdk:11-jre-hotspot WORKDIR application COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
假设上面的Dockerfile在当前目录中,可以使用docker build.或选择指定应用程序jar的路径来构建你的docker镜像,如下例所示:
docker build --build-arg JAR_FILE=path/to/myapp.jar .
这是一个多级dockerfile。构建器阶段提取稍后需要的目录。每个复制命令都与jarmode提取的层相关。
当然,可以不使用jarmode编写Dockerfile。你可以使用解压缩和mv的一些组合来将内容移动到正确的层,但是jarmode简化了这一点。
构建包
Dockerfiles只是构建docker映像的一种方法。另一种构建docker映像的方法是直接从Maven或Gradle插件使用buildpacks。如果你曾经使用过诸如Cloud Foundry或Heroku这样的应用程序平台,那么你可能已经使用过buildpack。BuildPack是平台的一部分,它将应用程序转换为平台可以实际运行的内容。例如,CloudFoundry的JavaBuildPack会注意到你正在推送一个.jar文件并自动添加一个相关的JRE。
使用Cloud Native Buildpacks,你可以创建可在任何地方运行的Docker兼容映像。springboot包括直接支持Maven和Gradle的buildpack。这意味着你只需键入一个命令,就可以在本地运行的Docker守护进程中快速获得一个合理的映像。