{"id":39952,"date":"2022-11-23T03:47:34","date_gmt":"2022-11-22T04:03:37","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/"},"modified":"2024-04-29T02:02:53","modified_gmt":"2024-04-28T18:02:53","slug":"%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/","title":{"rendered":"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API"},"content":{"rendered":"<h1>\u603b\u7ed3<\/h1>\n<p>\u9019\u7bc7\u6587\u7ae0\u662f\u95dc\u65bc\u4f7f\u7528Kotlin with Spring Boot 1.5\u4f86\u5be6\u73fe\u7c21\u55ae\u7684Rest API\u7684\uff0c\u4f46\u9019\u662fSpring Boot 2.0\u7248\u672c\u7684\u6587\u7ae0\u3002\u6211\u5011\u4f7f\u7528\u76ee\u524d\u6700\u65b0\u7248\u672c\u7684RC2(2018\/2)\u4f86\u9032\u884c\u5be6\u4f5c\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">2018\/3\/1\u306bSpring Boot 2.0.0 GA\u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\u3002(Spring Boot 2.0 goes GA)<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">2018\/5\/9\u306bSpring Boot 2.0.2\u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\u306e\u3067\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304a\u3088\u3073\u8a18\u4e8b\u3092\u4fee\u6b63\u3057\u307e\u3057\u305f\u3002(Spring Boot 2.0.2)<\/ul>\n<p>\u6e90\u4ee3\u7801\u4f4d\u4e8erubytomato\/demo-kotlin-spring2\u3002<\/p>\n<p>\u73af\u5883<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Windows 10 Professional<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Java 1.8.0_172<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Kotlin 1.2.31<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Spring Boot 2.0.2<\/ul>\n<\/li>\n<\/ul>\n<p>Spring Framework 5.0.5<br \/>\nMySQL 5.7.19<br \/>\nGradle 4.5.1<\/p>\n<p>IntelliJ IDEA 2017.3<\/p>\n<p>\u8bf7\u53c2\u8003\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Spring Boot 2.0 Release Notes<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">Spring Boot with Java 9 and above<\/ul>\n<p>\u5982\u679c\u8981\u8fdb\u884c1.5\u7248\u672c\u7684\u8fc1\u79fb<\/p>\n<p>\u5df2\u7ecf\u51c6\u5907\u597d\u4e86Spring Boot 2.0\u8fc1\u79fb\u6307\u5357\u3002<\/p>\n<h1>\u5e94\u7528\u7a0b\u5e8f x\u00f9)<\/h1>\n<p>\u5e94\u7528\u7a0b\u5e8f\u7684\u6a21\u677f\u662f\u901a\u8fc7Spring Initializr\u751f\u6210\u7684\u3002<br \/>\n\u751f\u6210\u7684build.gradle\u6587\u4ef6\u4e2d\u6307\u5b9a\u4e86Kotlin\u7248\u672c\u4e3a1.2.20\uff0c\u4f46\u662fSpring Boot 2.0.0\u652f\u6301\u7684\u7248\u672c\u53ef\u8fbe\u52301.2.21\uff0c\u56e0\u6b64\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u6211\u4eec\u4f7f\u7528\u4e861.2.21\u7248\u672c\u3002<\/p>\n<h2>\u6784\u5efa.gradle<\/h2>\n<pre class=\"post-pre\"><code><span class=\"n\">buildscript<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">ext<\/span> <span class=\"o\">{<\/span>\r\n        <span class=\"n\">kotlinVersion<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"1.2.31\"<\/span>\r\n        <span class=\"n\">springBootVersion<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"2.0.2.RELEASE\"<\/span>\r\n    <span class=\"o\">}<\/span>\r\n    <span class=\"n\">repositories<\/span> <span class=\"o\">{<\/span>\r\n        <span class=\"n\">mavenCentral<\/span><span class=\"o\">()<\/span>\r\n    <span class=\"o\">}<\/span>\r\n    <span class=\"n\">dependencies<\/span> <span class=\"o\">{<\/span>\r\n        <span class=\"n\">classpath<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}\"<\/span><span class=\"o\">)<\/span>\r\n        <span class=\"n\">classpath<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}\"<\/span><span class=\"o\">)<\/span>\r\n        <span class=\"n\">classpath<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}\"<\/span><span class=\"o\">)<\/span>\r\n        <span class=\"n\">classpath<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.jetbrains.kotlin:kotlin-noarg:${kotlinVersion}\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"o\">}<\/span>\r\n<span class=\"o\">}<\/span>\r\n\r\n<span class=\"n\">apply<\/span> <span class=\"nl\">plugin:<\/span> <span class=\"s2\">\"kotlin\"<\/span>\r\n<span class=\"n\">apply<\/span> <span class=\"nl\">plugin:<\/span> <span class=\"s2\">\"kotlin-spring\"<\/span>\r\n<span class=\"n\">apply<\/span> <span class=\"nl\">plugin:<\/span> <span class=\"s2\">\"kotlin-jpa\"<\/span>\r\n<span class=\"n\">apply<\/span> <span class=\"nl\">plugin:<\/span> <span class=\"s2\">\"org.springframework.boot\"<\/span>\r\n<span class=\"n\">apply<\/span> <span class=\"nl\">plugin:<\/span> <span class=\"s2\">\"io.spring.dependency-management\"<\/span>\r\n<span class=\"n\">apply<\/span> <span class=\"nl\">plugin:<\/span> <span class=\"s2\">\"kotlin-kapt\"<\/span>\r\n\r\n<span class=\"n\">group<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"com.example\"<\/span>\r\n<span class=\"n\">version<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"0.0.3-SNAPSHOT\"<\/span>\r\n<span class=\"n\">sourceCompatibility<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">1.8<\/span>\r\n<span class=\"n\">targetCompatibility<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">1.8<\/span>\r\n<span class=\"n\">compileKotlin<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">kotlinOptions<\/span> <span class=\"o\">{<\/span>\r\n        <span class=\"n\">freeCompilerArgs<\/span> <span class=\"o\">=<\/span> <span class=\"o\">[<\/span><span class=\"s2\">\"-Xjsr305=strict\"<\/span><span class=\"o\">]<\/span>\r\n        <span class=\"n\">jvmTarget<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"1.8\"<\/span>\r\n    <span class=\"o\">}<\/span>\r\n<span class=\"o\">}<\/span>\r\n<span class=\"n\">compileTestKotlin<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">kotlinOptions<\/span> <span class=\"o\">{<\/span>\r\n        <span class=\"n\">freeCompilerArgs<\/span> <span class=\"o\">=<\/span> <span class=\"o\">[<\/span><span class=\"s2\">\"-Xjsr305=strict\"<\/span><span class=\"o\">]<\/span>\r\n        <span class=\"n\">jvmTarget<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"1.8\"<\/span>\r\n    <span class=\"o\">}<\/span>\r\n<span class=\"o\">}<\/span>\r\n<span class=\"n\">compileJava<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">options<\/span><span class=\"o\">.<\/span><span class=\"na\">compilerArgs<\/span> <span class=\"o\">&lt;&lt;<\/span> <span class=\"s2\">\"-Xlint:unchecked,deprecation\"<\/span>\r\n<span class=\"o\">}<\/span>\r\n<span class=\"n\">compileTestJava<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">options<\/span><span class=\"o\">.<\/span><span class=\"na\">compilerArgs<\/span> <span class=\"o\">&lt;&lt;<\/span> <span class=\"s2\">\"-Xlint:unchecked,deprecation\"<\/span>\r\n<span class=\"o\">}<\/span>\r\n\r\n<span class=\"n\">repositories<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">mavenCentral<\/span><span class=\"o\">()<\/span>\r\n<span class=\"o\">}<\/span>\r\n\r\n<span class=\"n\">dependencies<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"c1\">\/\/ for web<\/span>\r\n    <span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-starter-web\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"com.fasterxml.jackson.module:jackson-module-kotlin\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"c1\">\/\/ for db<\/span>\r\n    <span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-starter-data-jpa\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"n\">runtime<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"mysql:mysql-connector-java\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"c1\">\/\/ compile(\"javax.xml.bind:jaxb-api:2.1\")<\/span>\r\n    <span class=\"c1\">\/\/ kotlin<\/span>\r\n    <span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.jetbrains.kotlin:kotlin-stdlib-jdk8\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.jetbrains.kotlin:kotlin-reflect\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"c1\">\/\/ for dev<\/span>\r\n    <span class=\"n\">kapt<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-configuration-processor\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"n\">runtime<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-devtools\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"n\">compileOnly<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-configuration-processor\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"c1\">\/\/ for test<\/span>\r\n    <span class=\"n\">testCompile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-starter-test\"<\/span><span class=\"o\">)<\/span>\r\n    <span class=\"n\">testCompile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"com.h2database:h2\"<\/span><span class=\"o\">)<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/code><\/pre>\n<h3>-Xjsr305\u7f16\u8bd1\u5668\u6807\u5fd7<\/h3>\n<p>\u5728\u4f7f\u7528Spring Initializr\u751f\u6210\u7684\u9879\u76ee\u4e2d\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u4f1a\u542f\u7528\u4e25\u683c\u6a21\u5f0f\u3002<br \/>\n\u5728\u4e25\u683c\u6a21\u5f0f\u4e0b\uff0c\u5982\u679cJava\u7aef\u7684\u5bf9\u8c61\u5b57\u6bb5\u4e0a\u6709Nullable\u6ce8\u89e3\uff0c\u5219\u5728Kotlin\u7aef\u4e0d\u5c06\u5176\u89c6\u4e3aNullable\u5c06\u5bfc\u81f4\u7f16\u8bd1\u9519\u8bef\u3002<\/p>\n<p>\u4f8b\u5982\uff0c\u4ee5\u4e0b\u4ee3\u7801\u4e2d\u7684result.body.id\u5904\u5c06\u4f1a\u5bfc\u81f4\u7f16\u8bd1\u9519\u8bef\u3002\uff08\u5728\u975e\u4e25\u683c\u6a21\u5f0f\u4e0b\u4e0d\u4f1a\u4ea7\u751f\u7f16\u8bd1\u9519\u8bef\uff0c\u4f46\u4f1a\u4ea7\u751f\u8b66\u544a\u3002\uff09<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@Test<\/span>\r\n<span class=\"k\">fun<\/span> <span class=\"nf\">`test<\/span> <span class=\"k\">get<\/span><span class=\"err\">`<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">val<\/span> <span class=\"py\">result<\/span><span class=\"p\">:<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">=<\/span> <span class=\"n\">testRestTemplate<\/span><span class=\"p\">.<\/span><span class=\"nf\">getForEntity<\/span><span class=\"p\">(<\/span><span class=\"s\">\"\/memo\/1\"<\/span><span class=\"p\">,<\/span> <span class=\"nc\">Memo<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">body<\/span><span class=\"p\">.<\/span><span class=\"n\">id<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"mi\">1L<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"c1\">\/\/ Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Memo? :compileTestKotlin FAILED<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u662f\u56e0\u4e3abody\u5b57\u6bb5\u4e0a\u6709\u4e00\u4e2aNullable\u6ce8\u89e3\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kd\">public<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">HttpEntity<\/span><span class=\"o\">&lt;<\/span><span class=\"no\">T<\/span><span class=\"o\">&gt;<\/span> <span class=\"o\">{<\/span>\r\n\r\n    <span class=\"nd\">@Nullable<\/span>\r\n    <span class=\"kd\">private<\/span> <span class=\"kd\">final<\/span> <span class=\"no\">T<\/span> <span class=\"n\">body<\/span><span class=\"o\">;<\/span>\r\n\r\n<span class=\"o\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4e3a\u4e86\u901a\u8fc7\u7f16\u8bd1\uff0c\u9700\u8981\u5c06Nullable\u53c2\u6570\u8fdb\u884c\u5982\u4e0b\u5904\u7406\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">body<\/span><span class=\"o\">?.<\/span><span class=\"n\">id<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"mi\">1L<\/span><span class=\"p\">)<\/span>\r\n<span class=\"c1\">\/\/ \u3082\u3057\u304f\u306fresult.body!!.id<\/span>\r\n<\/code><\/pre>\n<h3>\u7ba1\u7406\u4f9d\u8d56\u6027<\/h3>\n<p>\u6211\u4eec\u9700\u8981\u4f7f\u7528\u63d2\u4ef6io.spring.dependency-management\u6765\u8fdb\u884c\u4f9d\u8d56\u7ba1\u7406\u3002<\/p>\n<h3>`javax.xml.bind` \u7ec4\u4ef6<\/h3>\n<p>\u5728Java9\u65f6\u5019\u4f1a\u9700\u8981\u6ce8\u91ca\u6389\u7684javax.xml.bind:jaxb-api\u4f9d\u8d56\u3002\u539f\u56e0\u53ef\u4ee5\u53c2\u8003https:\/\/github.com\/spring-projects\/spring-boot\/issues\/11205\u3002<\/p>\n<h3>json -&gt; JSON<\/h3>\n<p>\u4ece2.0\u7248\u672c\u5f00\u59cb\uff0c\u5df2\u7ecf\u63d0\u4f9b\u4e86\u4e00\u4e2a\u540d\u4e3aspring-boot-starter-json\u7684\u7528\u4e8e\u5904\u7406json\u7684starter\u3002\u5b83\u5df2\u7ecf\u5305\u542b\u5728spring-boot-starter-web\u7684\u4f9d\u8d56\u5173\u7cfb\u4e2d\uff0c\u56e0\u6b64\u4e0d\u9700\u8981\u989d\u5916\u6307\u5b9a\u3002\u4f46\u662f\u5728Kotlin\u4e2d\uff0c\u8fd8\u9700\u8981\u6dfb\u52a0com.fasterxml.jackson.module:jackson-module-kotlin\u4f5c\u4e3a\u4f9d\u8d56\u3002<\/p>\n<h2>\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u6587\u4ef6.yml<\/h2>\n<pre class=\"post-pre\"><code><span class=\"na\">spring<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">application<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">name<\/span><span class=\"pi\">:<\/span> <span class=\"s\">kotlin with spring-boot <\/span><span class=\"m\">2.0<\/span>\r\n  <span class=\"na\">output<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">ansi<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">enabled<\/span><span class=\"pi\">:<\/span> <span class=\"s\">detect<\/span>\r\n  <span class=\"na\">profiles<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">active<\/span><span class=\"pi\">:<\/span> <span class=\"s\">dev<\/span>\r\n  <span class=\"na\">datasource<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">url<\/span><span class=\"pi\">:<\/span> <span class=\"s\">jdbc:mysql:\/\/localhost:3306\/demo_db?useSSL=false<\/span>\r\n    <span class=\"na\">username<\/span><span class=\"pi\">:<\/span> <span class=\"s\">demo_user<\/span>\r\n    <span class=\"na\">password<\/span><span class=\"pi\">:<\/span> <span class=\"s\">demo_pass<\/span>\r\n    <span class=\"na\">hikari<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">connection-test-query<\/span><span class=\"pi\">:<\/span> <span class=\"s\">select <\/span><span class=\"m\">1<\/span>\r\n      <span class=\"na\">connection-timeout<\/span><span class=\"pi\">:<\/span> <span class=\"m\">10000<\/span>\r\n      <span class=\"na\">maximum-pool-size<\/span><span class=\"pi\">:<\/span> <span class=\"m\">2<\/span>\r\n      <span class=\"na\">minimum-idle<\/span><span class=\"pi\">:<\/span> <span class=\"m\">2<\/span>\r\n  <span class=\"na\">jpa<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">open-in-view<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n    <span class=\"na\">properties<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">hibernate<\/span><span class=\"pi\">:<\/span>\r\n        <span class=\"na\">show_sql<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n        <span class=\"na\">format_sql<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n        <span class=\"na\">use_sql_comments<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n        <span class=\"na\">generate_statistics<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n  <span class=\"na\">jackson<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">serialization<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">write-dates-as-timestamps<\/span><span class=\"pi\">:<\/span> <span class=\"no\">false<\/span>\r\n      <span class=\"na\">write-durations-as-timestamps<\/span><span class=\"pi\">:<\/span> <span class=\"no\">true<\/span>\r\n\r\n<span class=\"na\">server<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">servlet<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">context-path<\/span><span class=\"pi\">:<\/span> <span class=\"s\">\/app<\/span>\r\n  <span class=\"na\">port<\/span><span class=\"pi\">:<\/span> <span class=\"m\">9000<\/span>\r\n\r\n<span class=\"s\">logging.file<\/span><span class=\"pi\">:<\/span> <span class=\"s\">demo.log<\/span>\r\n<span class=\"na\">logging<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">file<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">max-size<\/span><span class=\"pi\">:<\/span> <span class=\"s\">50MB<\/span>\r\n    <span class=\"na\">max-history<\/span><span class=\"pi\">:<\/span> <span class=\"m\">10<\/span>\r\n  <span class=\"na\">level<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">root<\/span><span class=\"pi\">:<\/span> <span class=\"s\">info<\/span>\r\n    <span class=\"s\">org.springframework<\/span><span class=\"pi\">:<\/span> <span class=\"s\">info<\/span>\r\n    <span class=\"s\">org.hibernate<\/span><span class=\"pi\">:<\/span> <span class=\"s\">info<\/span>\r\n    <span class=\"s\">org.hibernate.SQL<\/span><span class=\"pi\">:<\/span> <span class=\"s\">debug<\/span>\r\n    <span class=\"s\">com.example.demo<\/span><span class=\"pi\">:<\/span> <span class=\"s\">debug<\/span>\r\n<\/code><\/pre>\n<p>\u4ece2.0\u7248\u672c\u5f00\u59cb\uff0c\u9ed8\u8ba4\u7684\u6570\u636e\u6e90\u5df2\u7ecf\u6539\u4e3aHikariCP\u3002<br \/>\n\u8981\u8bbe\u7f6eHikariCP\u7684\u5c5e\u6027\uff0c\u8bf7\u6307\u5b9a\u4e3aspring.datasource.hikari.*\u3002<\/p>\n<p>\u6b64\u5916\uff0c\u7531\u4e8e\u5df2\u7ecf\u5bf9\u547d\u540d\u7a7a\u95f4\u8fdb\u884c\u4e86\u66f4\u6539\uff0c\u56e0\u6b64\u51c6\u5907\u4e86\u652f\u6301\u4ece1.5\u7248\u672c\u8fc1\u79fb\u7684\u6a21\u5757\u3002\u4f7f\u7528\u53ea\u9700\u5c06\u4ee5\u4e0b\u6a21\u5757\u96c6\u6210\u5373\u53ef\u3002\u4e00\u65e6\u96c6\u6210\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u7684\u5c5e\u6027\u5b58\u5728\uff0c\u5c06\u5728\u63a7\u5236\u53f0\u663e\u793a\u8b66\u544a\uff0c\u5e76\u4e34\u65f6\u5c06\u5176\u8f6c\u6362\u4e3a\u65b0\u5c5e\u6027\u4ee5\u4fbf\u542f\u52a8\u3002<\/p>\n<p>Maven &#8211; \u4e13\u5bb6\uff0c\u884c\u5bb6<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;dependency&gt;<\/span>\r\n  <span class=\"nt\">&lt;groupId&gt;<\/span>org.springframework.boot<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n  <span class=\"nt\">&lt;artifactId&gt;<\/span>spring-boot-properties-migrator<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<\/code><\/pre>\n<p>Gradle\uff1a\u5de5\u5177<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">runtime<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-properties-migrator\"<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<h2>\u5e94\u7528\u7a0b\u5e8f\u7684\u542f\u52a8\u7c7b<\/h2>\n<p>\u4ece2.0\u7248\u672c\u8d77\uff0c\u5f15\u5165\u4e86\u4e00\u4e2a\u540d\u4e3arunApplication\u7684\u51fd\u6570\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2<\/span>\r\n\r\n<span class=\"nd\">@SpringBootApplication<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">DemoKotlin2Application<\/span>\r\n\r\n<span class=\"k\">fun<\/span> <span class=\"nf\">main<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Array<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">runApplication<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">DemoKotlin2Application<\/span><span class=\"p\">&gt;(*<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<h2>\u5b9e\u4f53\u548c\u4ed3\u5e93<\/h2>\n<p>\u7531\u4e8eSpring Data Jpa\u7684\u7248\u672c\u5347\u7ea7\uff0c\u4ed3\u5e93\u6709\u4e00\u4e9b\u8f7b\u5fae\u7684\u66f4\u6539\u3002<\/p>\n<p>\u5b9e\u4f53<\/p>\n<p>\u5f9e1.5\u7248\u672c\u8d77\uff0c\u4e26\u7121\u4efb\u4f55\u66f4\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.entity<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">java.io.Serializable<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">java.time.LocalDateTime<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">javax.persistence.*<\/span>\r\n\r\n<span class=\"nd\">@Entity<\/span>\r\n<span class=\"nd\">@Table<\/span><span class=\"p\">(<\/span><span class=\"n\">name<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"memo\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"kd\">data class<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"nd\">@Column<\/span><span class=\"p\">(<\/span><span class=\"n\">name<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"title\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">nullable<\/span> <span class=\"p\">=<\/span> <span class=\"k\">false<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">title<\/span><span class=\"p\">:<\/span> <span class=\"nc\">String<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nd\">@Column<\/span><span class=\"p\">(<\/span><span class=\"n\">name<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"description\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">nullable<\/span> <span class=\"p\">=<\/span> <span class=\"k\">false<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">description<\/span><span class=\"p\">:<\/span> <span class=\"nc\">String<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nd\">@Column<\/span><span class=\"p\">(<\/span><span class=\"n\">name<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"done\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">nullable<\/span> <span class=\"p\">=<\/span> <span class=\"k\">false<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">done<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Boolean<\/span> <span class=\"p\">=<\/span> <span class=\"k\">false<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nd\">@Column<\/span><span class=\"p\">(<\/span><span class=\"n\">name<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"updated\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">nullable<\/span> <span class=\"p\">=<\/span> <span class=\"k\">false<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">updated<\/span><span class=\"p\">:<\/span> <span class=\"nc\">LocalDateTime<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">LocalDateTime<\/span><span class=\"p\">.<\/span><span class=\"nf\">now<\/span><span class=\"p\">(),<\/span>\r\n    <span class=\"nd\">@Id<\/span>\r\n    <span class=\"nd\">@GeneratedValue<\/span><span class=\"p\">(<\/span><span class=\"n\">strategy<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">GenerationType<\/span><span class=\"p\">.<\/span><span class=\"nc\">IDENTITY<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Long<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">0<\/span>\r\n<span class=\"p\">)<\/span> <span class=\"p\">:<\/span> <span class=\"nc\">Serializable<\/span>\r\n<\/code><\/pre>\n<p>\u4ee3\u7801\u5e93<\/p>\n<p>\u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u5b9e\u73b0\u4e86JpaRepository\u63a5\u53e3\uff0c\u4f46\u662f\u7531\u4e8e\u8be5\u63a5\u53e3\u4e2d\u5b9a\u4e49\u7684\u65b9\u6cd5\u7b7e\u540d\u6709\u4e00\u4e9b\u53d8\u5316\uff0c\u6240\u4ee5\u5728\u4ece1.5\u7248\u672c\u8fc1\u79fb\u65f6\u53ef\u80fd\u9700\u8981\u4fee\u6539\u4ee3\u7801\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.repository<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.data.jpa.repository.JpaRepository<\/span>\r\n\r\n<span class=\"kd\">interface<\/span> <span class=\"nc\">MemoRepository<\/span> <span class=\"p\">:<\/span> <span class=\"nc\">JpaRepository<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">,<\/span> <span class=\"nc\">Long<\/span><span class=\"p\">&gt;<\/span>\r\n<\/code><\/pre>\n<ul class=\"post-ul\">\u30b7\u30b0\u30cd\u30c1\u30e3\u306e\u5909\u66f4\u70b9\u306f\u88dc\u8db3\u6b04\u306b\u307e\u3068\u3081\u3066\u3042\u308a\u307e\u3059\u3002<\/ul>\n<h2>\u670d\u52a1<\/h2>\n<p>\u4e0e1.5\u7248\u672c\u76f8\u6bd4\uff0c\u6ca1\u6709\u4ec0\u4e48\u503c\u5f97\u7279\u522b\u6ce8\u610f\u7684\u53d8\u5316\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.service<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.data.domain.Pageable<\/span>\r\n\r\n<span class=\"kd\">interface<\/span> <span class=\"nc\">MemoService<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Long<\/span><span class=\"p\">):<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">?<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"n\">page<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Pageable<\/span><span class=\"p\">):<\/span> <span class=\"nc\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">store<\/span><span class=\"p\">(<\/span><span class=\"n\">memo<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">removeById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Long<\/span><span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.service.impl<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.repository.MemoRepository<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.service.MemoService<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.data.domain.Pageable<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.stereotype.Service<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.transaction.annotation.Transactional<\/span>\r\n\r\n<span class=\"nd\">@Service<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">MemoServiceImpl<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"k\">private<\/span> <span class=\"kd\">val<\/span> <span class=\"py\">repository<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MemoRepository<\/span><span class=\"p\">)<\/span> <span class=\"p\">:<\/span> <span class=\"nc\">MemoService<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"nd\">@Transactional<\/span><span class=\"p\">(<\/span><span class=\"n\">readOnly<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Long<\/span><span class=\"p\">):<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">?<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">repository<\/span><span class=\"p\">.<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">).<\/span><span class=\"nf\">orElseGet<\/span><span class=\"p\">(<\/span><span class=\"k\">null<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Transactional<\/span><span class=\"p\">(<\/span><span class=\"n\">readOnly<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"n\">page<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Pageable<\/span><span class=\"p\">):<\/span> <span class=\"nc\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">repository<\/span><span class=\"p\">.<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"n\">page<\/span><span class=\"p\">).<\/span><span class=\"n\">content<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Transactional<\/span><span class=\"p\">(<\/span><span class=\"n\">timeout<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">10<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">store<\/span><span class=\"p\">(<\/span><span class=\"n\">memo<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">repository<\/span><span class=\"p\">.<\/span><span class=\"nf\">save<\/span><span class=\"p\">(<\/span><span class=\"n\">memo<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Transactional<\/span><span class=\"p\">(<\/span><span class=\"n\">timeout<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">10<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">removeById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Long<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">repository<\/span><span class=\"p\">.<\/span><span class=\"nf\">deleteById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<h2>\u63a7\u5236\u5668 q\u00ec)<\/h2>\n<p>\u4e0e1.5\u76f8\u6bd4\uff0c\u5e76\u65e0\u503c\u5f97\u7279\u522b\u6ce8\u610f\u7684\u53d8\u5316\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.controller<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.service.MemoService<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.data.domain.Pageable<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.http.HttpStatus<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.http.MediaType<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.http.ResponseEntity<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.web.bind.annotation.*<\/span>\r\n\r\n<span class=\"nd\">@RestController<\/span>\r\n<span class=\"nd\">@RequestMapping<\/span><span class=\"p\">(<\/span><span class=\"n\">path<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"memo\"<\/span><span class=\"p\">])<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">MemoController<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"k\">private<\/span> <span class=\"kd\">val<\/span> <span class=\"py\">service<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MemoService<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"nd\">@GetMapping<\/span><span class=\"p\">(<\/span><span class=\"n\">path<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"{id}\"<\/span><span class=\"p\">],<\/span> <span class=\"n\">produces<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON_UTF8_VALUE<\/span><span class=\"p\">])<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">id<\/span><span class=\"p\">(<\/span><span class=\"nd\">@PathVariable<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"id\"<\/span><span class=\"p\">)<\/span> <span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Long<\/span><span class=\"p\">):<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">memo<\/span> <span class=\"p\">=<\/span> <span class=\"n\">service<\/span><span class=\"p\">.<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">memo<\/span> <span class=\"p\">!=<\/span> <span class=\"k\">null<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">.<\/span><span class=\"nf\">ok<\/span><span class=\"p\">(<\/span><span class=\"n\">memo<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">(<\/span><span class=\"nc\">HttpStatus<\/span><span class=\"p\">.<\/span><span class=\"nc\">NOT_FOUND<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@GetMapping<\/span><span class=\"p\">(<\/span><span class=\"n\">path<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"list\"<\/span><span class=\"p\">],<\/span> <span class=\"n\">produces<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON_UTF8_VALUE<\/span><span class=\"p\">])<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">list<\/span><span class=\"p\">(<\/span><span class=\"n\">page<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Pageable<\/span><span class=\"p\">):<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;&gt;<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">.<\/span><span class=\"nf\">ok<\/span><span class=\"p\">(<\/span><span class=\"n\">service<\/span><span class=\"p\">.<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"n\">page<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@PostMapping<\/span><span class=\"p\">(<\/span><span class=\"n\">produces<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">TEXT_PLAIN_VALUE<\/span><span class=\"p\">],<\/span> <span class=\"n\">consumes<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON_UTF8_VALUE<\/span><span class=\"p\">])<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">store<\/span><span class=\"p\">(<\/span><span class=\"nd\">@RequestBody<\/span> <span class=\"n\">memo<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">):<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">service<\/span><span class=\"p\">.<\/span><span class=\"nf\">store<\/span><span class=\"p\">(<\/span><span class=\"n\">memo<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">.<\/span><span class=\"nf\">ok<\/span><span class=\"p\">(<\/span><span class=\"s\">\"success\"<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@DeleteMapping<\/span><span class=\"p\">(<\/span><span class=\"n\">path<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"{id}\"<\/span><span class=\"p\">],<\/span> <span class=\"n\">produces<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">TEXT_PLAIN_VALUE<\/span><span class=\"p\">])<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">remove<\/span><span class=\"p\">(<\/span><span class=\"nd\">@PathVariable<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"id\"<\/span><span class=\"p\">)<\/span> <span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Long<\/span><span class=\"p\">):<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">service<\/span><span class=\"p\">.<\/span><span class=\"nf\">removeById<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nc\">ResponseEntity<\/span><span class=\"p\">.<\/span><span class=\"nf\">ok<\/span><span class=\"p\">(<\/span><span class=\"s\">\"success\"<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<ul class=\"post-ul\">\u30da\u30fc\u30b8\u30f3\u30b0\u3001\u30bd\u30fc\u30c8\u306e\u8a2d\u5b9a\u3092\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3067\u304d\u308b\u30d7\u30ed\u30d1\u30c6\u30a3\u304c\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/ul>\n<pre class=\"post-pre\"><code>spring.data.web.pageable.*\r\nspring.data.web.sort.*\r\n<\/code><\/pre>\n<p>\u4f8b\u5982\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u5c5e\u6027\u6765\u8bbe\u7f6e\u6bcf\u9875\u663e\u793a\u7684\u6700\u5927\u6570\u91cf\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.data.web.pageable.default-page-size= 10\r\n<\/code><\/pre>\n<h1>\u9a8c\u8bc1API\u7684\u8fd0\u4f5c<\/h1>\n<p>\u641c\u7d22<\/p>\n<pre class=\"post-pre\"><code>&gt; curl -v http:\/\/localhost:9000\/app\/memo\/1\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>&gt; curl -v http:\/\/localhost:9000\/app\/memo\/list\r\n<\/code><\/pre>\n<p>\u7ffb\u9875<\/p>\n<pre class=\"post-pre\"><code>&gt; curl -v http:\/\/localhost:9000\/app\/memo\/list?page=0&amp;size=10\r\n<\/code><\/pre>\n<p>\u6ce8\u518c\u65b0\u7528\u6237<\/p>\n<pre class=\"post-pre\"><code>&gt; curl -v -H \"Content-Type:application\/json\" -d @memo.json -X POST http:\/\/localhost:9000\/app\/memo\r\n<\/code><\/pre>\n<p>\u5220\u9664<\/p>\n<pre class=\"post-pre\"><code>&gt; curl -v -X DELETE http:\/\/localhost:9000\/app\/memo\/1\r\n<\/code><\/pre>\n<h1>\u8003\u8bd5\u4ee3\u7801<\/h1>\n<h2>\u4ed3\u5e93\u7684\u5355\u5143\u6d4b\u8bd5<\/h2>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.repository<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.junit.Test<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.junit.runner.RunWith<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.beans.factory.annotation.Autowired<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.context.junit4.SpringRunner<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.assertj.core.api.Assertions.*<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.context.jdbc.Sql<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">java.time.LocalDateTime<\/span>\r\n\r\n<span class=\"nd\">@RunWith<\/span><span class=\"p\">(<\/span><span class=\"nc\">SpringRunner<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nd\">@DataJpaTest<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">MemoRepositoryTests<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"nd\">@Autowired<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">entityManager<\/span><span class=\"p\">:<\/span> <span class=\"nc\">TestEntityManager<\/span>\r\n\r\n    <span class=\"nd\">@Autowired<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">sut<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MemoRepository<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"nd\">@Sql<\/span><span class=\"p\">(<\/span><span class=\"n\">statements<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"INSERT INTO memo (id, title, description, done, updated) VALUES (1, 'memo test', 'memo description', FALSE, CURRENT_TIMESTAMP)\"<\/span><span class=\"p\">])<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">findById<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expected<\/span> <span class=\"p\">=<\/span> <span class=\"n\">entityManager<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">(<\/span><span class=\"nc\">Memo<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1L<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">actual<\/span> <span class=\"p\">=<\/span> <span class=\"n\">sut<\/span><span class=\"p\">.<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"n\">id<\/span><span class=\"p\">).<\/span><span class=\"nf\">orElseGet<\/span> <span class=\"p\">{<\/span> <span class=\"k\">null<\/span> <span class=\"p\">}<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">isNotNull<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">save<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">updated<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">LocalDateTime<\/span><span class=\"p\">.<\/span><span class=\"nf\">of<\/span><span class=\"p\">(<\/span><span class=\"mi\">2018<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">19<\/span><span class=\"p\">,<\/span> <span class=\"mi\">18<\/span><span class=\"p\">,<\/span> <span class=\"mi\">12<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expected<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">(<\/span><span class=\"n\">title<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"test title\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">description<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"test description\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">done<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span><span class=\"p\">,<\/span> <span class=\"n\">updated<\/span> <span class=\"p\">=<\/span> <span class=\"n\">updated<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"n\">sut<\/span><span class=\"p\">.<\/span><span class=\"nf\">saveAndFlush<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">actual<\/span> <span class=\"p\">=<\/span> <span class=\"n\">entityManager<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">(<\/span><span class=\"nc\">Memo<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">,<\/span> <span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"nd\">@Sql<\/span><span class=\"p\">(<\/span><span class=\"n\">statements<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"INSERT INTO memo (id, title, description, done, updated) VALUES (1, 'memo test', 'memo description', FALSE, CURRENT_TIMESTAMP)\"<\/span><span class=\"p\">])<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">delete<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expected<\/span> <span class=\"p\">=<\/span> <span class=\"n\">entityManager<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">(<\/span><span class=\"nc\">Memo<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1L<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"n\">sut<\/span><span class=\"p\">.<\/span><span class=\"nf\">deleteById<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"n\">sut<\/span><span class=\"p\">.<\/span><span class=\"nf\">flush<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">actual<\/span> <span class=\"p\">=<\/span> <span class=\"n\">entityManager<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">(<\/span><span class=\"nc\">Memo<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">,<\/span> <span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">isNull<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<h2>\u670d\u52a1\u7684\u5355\u5143\u6d4b\u8bd5<\/h2>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.service<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.repository.MemoRepository<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.service.impl.MemoServiceImpl<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.junit.*<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.mockito.*<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.mockito.Mockito.*<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.mockito.junit.MockitoJUnit<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.mockito.junit.MockitoRule<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.mockito.quality.Strictness<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.assertj.core.api.Assertions.*<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.data.domain.PageImpl<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.data.domain.PageRequest<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">java.util.*<\/span>\r\n\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">MemoServiceImplTests<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"nd\">@Rule<\/span>\r\n    <span class=\"nd\">@JvmField<\/span>\r\n    <span class=\"kd\">val<\/span> <span class=\"py\">rule<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MockitoRule<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">MockitoJUnit<\/span><span class=\"p\">.<\/span><span class=\"nf\">rule<\/span><span class=\"p\">().<\/span><span class=\"nf\">strictness<\/span><span class=\"p\">(<\/span><span class=\"nc\">Strictness<\/span><span class=\"p\">.<\/span><span class=\"nc\">STRICT_STUBS<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"nd\">@Mock<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">repository<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MemoRepository<\/span>\r\n\r\n    <span class=\"nd\">@InjectMocks<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">sut<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MemoServiceImpl<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">findById<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expected<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">Optional<\/span><span class=\"p\">.<\/span><span class=\"nf\">ofNullable<\/span><span class=\"p\">(<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">11<\/span><span class=\"p\">,<\/span> <span class=\"n\">title<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"title\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">description<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"description\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">done<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span><span class=\"p\">))<\/span>\r\n        <span class=\"nc\">Mockito<\/span><span class=\"p\">.<\/span><span class=\"nf\">`when`<\/span><span class=\"p\">(<\/span><span class=\"n\">repository<\/span><span class=\"p\">.<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"nf\">anyLong<\/span><span class=\"p\">())).<\/span><span class=\"nf\">thenReturn<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">actual<\/span> <span class=\"p\">=<\/span> <span class=\"n\">sut<\/span><span class=\"p\">.<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"mi\">11<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">isNotNull<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"k\">get<\/span><span class=\"p\">())<\/span>\r\n\r\n        <span class=\"nf\">verify<\/span><span class=\"p\">(<\/span><span class=\"n\">repository<\/span><span class=\"p\">,<\/span> <span class=\"nf\">times<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)).<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"nf\">anyLong<\/span><span class=\"p\">())<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">findAllWithEmptyList<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">pageable<\/span><span class=\"p\">:<\/span> <span class=\"nc\">PageRequest<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">PageRequest<\/span><span class=\"p\">.<\/span><span class=\"nf\">of<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expected<\/span> <span class=\"p\">=<\/span> <span class=\"n\">emptyList<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;()<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">page<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">PageImpl<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;(<\/span><span class=\"n\">expected<\/span><span class=\"p\">,<\/span> <span class=\"n\">pageable<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nc\">Mockito<\/span><span class=\"p\">.<\/span><span class=\"nf\">`when`<\/span><span class=\"p\">(<\/span><span class=\"n\">repository<\/span><span class=\"p\">.<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"nf\">eq<\/span><span class=\"p\">(<\/span><span class=\"n\">pageable<\/span><span class=\"p\">))).<\/span><span class=\"nf\">thenReturn<\/span><span class=\"p\">(<\/span><span class=\"n\">page<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">actual<\/span> <span class=\"p\">=<\/span> <span class=\"n\">sut<\/span><span class=\"p\">.<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"n\">pageable<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">hasSize<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"nf\">verify<\/span><span class=\"p\">(<\/span><span class=\"n\">repository<\/span><span class=\"p\">,<\/span> <span class=\"nf\">times<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)).<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"nf\">eq<\/span><span class=\"p\">(<\/span><span class=\"n\">pageable<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">findAll<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">pageable<\/span><span class=\"p\">:<\/span> <span class=\"nc\">PageRequest<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">PageRequest<\/span><span class=\"p\">.<\/span><span class=\"nf\">of<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expected<\/span> <span class=\"p\">=<\/span> <span class=\"nf\">listOf<\/span><span class=\"p\">(<\/span>\r\n            <span class=\"nc\">Memo<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">title<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"title A\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">description<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"desc A\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">done<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span><span class=\"p\">),<\/span>\r\n            <span class=\"nc\">Memo<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"n\">title<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"title B\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">description<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"desc B\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">done<\/span> <span class=\"p\">=<\/span> <span class=\"k\">false<\/span><span class=\"p\">),<\/span>\r\n            <span class=\"nc\">Memo<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span> <span class=\"n\">title<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"title C\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">description<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"desc C\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">done<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"p\">)<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">page<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">PageImpl<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;(<\/span><span class=\"n\">expected<\/span><span class=\"p\">,<\/span> <span class=\"n\">pageable<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nc\">Mockito<\/span><span class=\"p\">.<\/span><span class=\"nf\">`when`<\/span><span class=\"p\">(<\/span><span class=\"n\">repository<\/span><span class=\"p\">.<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"nf\">eq<\/span><span class=\"p\">(<\/span><span class=\"n\">pageable<\/span><span class=\"p\">))).<\/span><span class=\"nf\">thenReturn<\/span><span class=\"p\">(<\/span><span class=\"n\">page<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">actual<\/span> <span class=\"p\">=<\/span> <span class=\"n\">sut<\/span><span class=\"p\">.<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"n\">pageable<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">hasSize<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">actual<\/span><span class=\"p\">).<\/span><span class=\"nf\">containsSequence<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"nf\">verify<\/span><span class=\"p\">(<\/span><span class=\"n\">repository<\/span><span class=\"p\">,<\/span> <span class=\"nf\">times<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)).<\/span><span class=\"nf\">findAll<\/span><span class=\"p\">(<\/span><span class=\"nf\">eq<\/span><span class=\"p\">(<\/span><span class=\"n\">pageable<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<h2>\u63a7\u5236\u5668\u7684\u6d4b\u8bd5<\/h2>\n<h3>\u5355\u4f53<\/h3>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.controller<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.service.MemoService<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.fasterxml.jackson.databind.ObjectMapper<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.assertj.core.api.Assertions.assertThat<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.junit.Test<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.junit.runner.RunWith<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.mockito.ArgumentMatchers.anyLong<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.mockito.Mockito<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.beans.factory.annotation.Autowired<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.boot.test.mock.mockito.MockBean<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.http.MediaType<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.context.junit4.SpringRunner<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.web.servlet.MockMvc<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.web.servlet.request.MockMvcRequestBuilders<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.web.servlet.result.MockMvcResultMatchers.*<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.web.servlet.result.MockMvcResultHandlers.print<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">java.nio.charset.Charset<\/span>\r\n\r\n<span class=\"nd\">@RunWith<\/span><span class=\"p\">(<\/span><span class=\"nc\">SpringRunner<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nd\">@WebMvcTest<\/span><span class=\"p\">(<\/span><span class=\"nc\">MemoController<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">)<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">MemoControllerTests<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"nd\">@Autowired<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">mvc<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MockMvc<\/span>\r\n    <span class=\"nd\">@Autowired<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">objectMapper<\/span><span class=\"p\">:<\/span> <span class=\"nc\">ObjectMapper<\/span>\r\n    <span class=\"nd\">@MockBean<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">memoService<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MemoService<\/span>\r\n\r\n    <span class=\"k\">private<\/span> <span class=\"kd\">val<\/span> <span class=\"py\">contentType<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">MediaType<\/span><span class=\"p\">(<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON<\/span><span class=\"p\">.<\/span><span class=\"n\">type<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON<\/span><span class=\"p\">.<\/span><span class=\"n\">subtype<\/span><span class=\"p\">,<\/span> <span class=\"nc\">Charset<\/span><span class=\"p\">.<\/span><span class=\"nf\">forName<\/span><span class=\"p\">(<\/span><span class=\"s\">\"utf8\"<\/span><span class=\"p\">))<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">getOne<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expected<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">Memo<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">=<\/span><span class=\"mi\">1L<\/span><span class=\"p\">,<\/span> <span class=\"n\">title<\/span><span class=\"p\">=<\/span><span class=\"s\">\"test title\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">description<\/span><span class=\"p\">=<\/span><span class=\"s\">\"test description\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">done<\/span><span class=\"p\">=<\/span><span class=\"k\">true<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">expectedJson<\/span> <span class=\"p\">=<\/span> <span class=\"n\">objectMapper<\/span><span class=\"p\">.<\/span><span class=\"nf\">writeValueAsString<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nc\">Mockito<\/span><span class=\"p\">.<\/span><span class=\"nf\">`when`<\/span><span class=\"p\">(<\/span><span class=\"n\">memoService<\/span><span class=\"p\">.<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"nf\">anyLong<\/span><span class=\"p\">())).<\/span><span class=\"nf\">thenReturn<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">builder<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">MockMvcRequestBuilders<\/span><span class=\"p\">.<\/span><span class=\"k\">get<\/span><span class=\"p\">(<\/span><span class=\"s\">\"\/memo\/{id}\"<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">accept<\/span><span class=\"p\">(<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON_UTF8<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">result<\/span> <span class=\"p\">=<\/span> <span class=\"n\">mvc<\/span><span class=\"p\">.<\/span><span class=\"nf\">perform<\/span><span class=\"p\">(<\/span><span class=\"n\">builder<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andExpect<\/span><span class=\"p\">(<\/span><span class=\"nf\">status<\/span><span class=\"p\">().<\/span><span class=\"n\">isOk<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andExpect<\/span><span class=\"p\">(<\/span><span class=\"nf\">content<\/span><span class=\"p\">().<\/span><span class=\"nf\">contentType<\/span><span class=\"p\">(<\/span><span class=\"n\">contentType<\/span><span class=\"p\">))<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andExpect<\/span><span class=\"p\">(<\/span><span class=\"nf\">jsonPath<\/span><span class=\"p\">(<\/span><span class=\"s\">\"$\"<\/span><span class=\"p\">).<\/span><span class=\"n\">isNotEmpty<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andExpect<\/span><span class=\"p\">(<\/span><span class=\"nf\">jsonPath<\/span><span class=\"p\">(<\/span><span class=\"s\">\"$.title\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">value<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"n\">title<\/span><span class=\"p\">))<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andExpect<\/span><span class=\"p\">(<\/span><span class=\"nf\">jsonPath<\/span><span class=\"p\">(<\/span><span class=\"s\">\"$.description\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">value<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"n\">description<\/span><span class=\"p\">))<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andExpect<\/span><span class=\"p\">(<\/span><span class=\"nf\">jsonPath<\/span><span class=\"p\">(<\/span><span class=\"s\">\"$.done\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">value<\/span><span class=\"p\">(<\/span><span class=\"n\">expected<\/span><span class=\"p\">.<\/span><span class=\"n\">done<\/span><span class=\"p\">))<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andDo<\/span><span class=\"p\">(<\/span><span class=\"nf\">`print`<\/span><span class=\"p\">())<\/span>\r\n                <span class=\"p\">.<\/span><span class=\"nf\">andReturn<\/span><span class=\"p\">()<\/span>\r\n\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">response<\/span><span class=\"p\">.<\/span><span class=\"n\">contentAsString<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"n\">expectedJson<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<h3>\u878d\u5408<\/h3>\n<pre class=\"post-pre\"><code><span class=\"k\">package<\/span> <span class=\"nn\">com.example.demokotlin2.controller<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.DemoKotlin2Application<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">com.example.demokotlin2.entity.Memo<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.junit.Test<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.junit.runner.RunWith<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.beans.factory.annotation.Autowired<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.boot.test.context.SpringBootTest<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.boot.test.web.client.TestRestTemplate<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.test.context.junit4.SpringRunner<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.assertj.core.api.Assertions.*<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.http.HttpStatus<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.http.MediaType<\/span>\r\n\r\n<span class=\"nd\">@RunWith<\/span><span class=\"p\">(<\/span><span class=\"nc\">SpringRunner<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nd\">@SpringBootTest<\/span><span class=\"p\">(<\/span><span class=\"n\">classes<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"nc\">DemoKotlin2Application<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">],<\/span>\r\n    <span class=\"n\">webEnvironment<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">SpringBootTest<\/span><span class=\"p\">.<\/span><span class=\"nc\">WebEnvironment<\/span><span class=\"p\">.<\/span><span class=\"nc\">RANDOM_PORT<\/span><span class=\"p\">)<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">MemoControllerTests<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"kd\">class<\/span> <span class=\"nc\">MemoList<\/span> <span class=\"p\">:<\/span> <span class=\"nc\">MutableList<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Memo<\/span><span class=\"p\">&gt;<\/span> <span class=\"k\">by<\/span> <span class=\"nc\">ArrayList<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"nd\">@Autowired<\/span>\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">testRestTemplate<\/span><span class=\"p\">:<\/span> <span class=\"nc\">TestRestTemplate<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">getOne<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">result<\/span> <span class=\"p\">=<\/span> <span class=\"n\">testRestTemplate<\/span><span class=\"p\">.<\/span><span class=\"nf\">getForEntity<\/span><span class=\"p\">(<\/span><span class=\"s\">\"\/memo\/1\"<\/span><span class=\"p\">,<\/span> <span class=\"nc\">Memo<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">).<\/span><span class=\"n\">isNotNull<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">statusCode<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"nc\">HttpStatus<\/span><span class=\"p\">.<\/span><span class=\"nc\">OK<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">headers<\/span><span class=\"p\">.<\/span><span class=\"n\">contentType<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON_UTF8<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">body<\/span><span class=\"o\">?.<\/span><span class=\"n\">id<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"mi\">1L<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"nd\">@Test<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">pagination<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">val<\/span> <span class=\"py\">result<\/span> <span class=\"p\">=<\/span> <span class=\"n\">testRestTemplate<\/span><span class=\"p\">.<\/span><span class=\"nf\">getForEntity<\/span><span class=\"p\">(<\/span><span class=\"s\">\"\/memo\/list?page={page}&amp;size={size}\"<\/span><span class=\"p\">,<\/span> <span class=\"nc\">MemoList<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">).<\/span><span class=\"n\">isNotNull<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">statusCode<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"nc\">HttpStatus<\/span><span class=\"p\">.<\/span><span class=\"nc\">OK<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">headers<\/span><span class=\"p\">.<\/span><span class=\"n\">contentType<\/span><span class=\"p\">).<\/span><span class=\"nf\">isEqualTo<\/span><span class=\"p\">(<\/span><span class=\"nc\">MediaType<\/span><span class=\"p\">.<\/span><span class=\"nc\">APPLICATION_JSON_UTF8<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">assertThat<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"n\">body<\/span><span class=\"p\">).<\/span><span class=\"nf\">hasSize<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<h1>\u8865\u5145<\/h1>\n<h2>M1\u81f3M7\u3001RC1\u548cRC2\u7684\u53d1\u5e03\u8bf4\u660e<\/h2>\n<p>\u6211\u5927\u81f4\u603b\u7ed3\u4e86\u4eceM1\u5230RC2\u7684\u53d1\u5e03\u8bf4\u660e\u7684\u5185\u5bb9\u3002\uff082018\u5e742\u670819\u65e5\uff09<br \/>\n\u4f46\u662f\uff0c\u7531\u4e8e\u65f6\u95f4\u4e0a\u7684\u9650\u5236\uff0c\u6211\u65e0\u6cd5\u68c0\u67e5\u548c\u9a8c\u8bc1\u6240\u6709\u5185\u5bb9\uff0c\u6240\u4ee5\u6211\u53ea\u6311\u9009\u4e86\u4e2a\u4eba\u611f\u5174\u8da3\u548c\u4f3c\u4e4e\u5f71\u54cd\u8f83\u5927\u7684\u90e8\u5206\u3002<\/p>\n<h3>Spring-Boot-2.0.0-M1-\u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 M1 Configuration Changelog<\/ul>\n<h4>\u2605\u57fa\u7ebf\u7684\u4fee\u6539<\/h4>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Java8 or later\u304c\u5fc5\u8981\u3067\u3059\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">Java6,7\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u307e\u305b\u3093\u3002<\/ul>\n<h4>\u2605\u66f4\u6539\u4e3b\u8981\u4f9d\u8d56\u7248\u672c<\/h4>\n<div>\n<div class=\"post-table\">componentSpring Boot 1.5.10Spring Boot 2.0.0Spring Framework4.3.145.0.4 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Spring Security4.2.45.0.3 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Spring Data Commons1.13.02.0.5 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Spring Data Jpa1.11.102.0.5 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Aspectj1.8.131.8.13javassist3.21.0-GA3.22.0-GA <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Jetty9.4.89.4.8Tomcat8.5.278.5.28 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Undertow1.4.221.4.22Hibernate5.0.125.2.14 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Jackson2.8.102.9.4 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Gson2.8.22.8.2JUnit4.124.12JUnit-Jupiter<br \/>\n5.1.0mockito1.10.192.15.0 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>Maven3.2+3.2+Gradle2.9 or later4 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>flyway3.2.15.0.7 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>liquibase3.5.33.5.5 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>kotlin<br \/>\n1.2.21<\/div>\n<\/div>\n<h4>\u8f7b\u677e\u7ed1\u5b9a<\/h4>\n<ul class=\"post-ul\">Spring Boot Configuration Binding<\/ul>\n<p>\u7ee7\u7eed\u4f18\u5316\u4e86\u5c5e\u6027\u7684\u5bbd\u677e\u7ed1\u5b9a\uff08Relaxed binding\uff09\uff0c\u5177\u4f53\u4fe1\u606f\u53ef\u4ee5\u5728Relaxed Binding 2.0\u4e2d\u627e\u5230\u3002<\/p>\n<p>\u5c5e\u6027\u63cf\u8ff0\u65b9\u6cd5<\/p>\n<p>\u5728\u5c5e\u6027\u7684\u8868\u793a\u65b9\u6cd5\u4e2d\u6709\u4ee5\u4e0b\u9009\u9879\u3002<\/p>\n<div>\n<div class=\"post-table\">\u8a18\u6cd5exampledesccamel-caseperson.firstName<br \/>\nkebab-caseperson.first-name.properties\u3068.yml\u30d5\u30a1\u30a4\u30eb\u3067\u306e\u4f7f\u7528\u3092\u63a8\u5968snake-caseperson.first_namekebab-case\u306e\u4ee3\u66ffupper-casePERSON_FIRSTNAME\u30b7\u30b9\u30c6\u30e0\u74b0\u5883\u5909\u6570\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306b\u63a8\u5968<\/div>\n<\/div>\n<p>\u5c5e\u6027\u53ef\u4ee5\u6839\u636e(1)\u524d\u7f00\u548c(2)\u540d\u79f0\u8fdb\u884c\u533a\u5206\uff0c\u524d\u7f00\u548c\u540d\u79f0\u7684\u4f7f\u7528\u8bed\u6cd5\u662f\u4e0d\u540c\u7684\u3002<\/p>\n<pre class=\"post-pre\"><code>my-app.my-module.foo.first-name= ruby\r\n^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^  ^^^^\r\n |                    |           |\r\n(1)                  (2)         (3)\r\n<\/code><\/pre>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u524d\u7f00\uff1a\u8fde\u5b57\u7b26\u547d\u540d\u6cd5<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u540d\u79f0\uff1a\u8fde\u5b57\u7b26\u547d\u540d\u6cd5\u3001\u9a7c\u5cf0\u547d\u540d\u6cd5\u3001\u86c7\u5f62\u547d\u540d\u6cd5<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\u503c\uff1a\u30d7\u30ed\u30d1\u30c6\u30a3\u7684\u503c<\/ol>\n<p>\u4ece2.0\u7248\u672c\u5f00\u59cb\uff0cConfigurationProperties\u6ce8\u89e3\u7684prefix\u5c5e\u6027\u7684\u7528\u6cd5\u53d1\u751f\u4e86\u53d8\u5316\u3002<\/p>\n<p>\u4f8b\u5982\uff0c\u4e3a\u4e86\u7ed1\u5b9a\u4ee5\u4e0b\u5c5e\u6027<\/p>\n<pre class=\"post-pre\"><code>my-app.my-module.foo.first-name= ruby\r\nmy-app.my-module.foo.last-name= tomato\r\nmy-app.my-module.foo.age= 10\r\n<\/code><\/pre>\n<p>\u53ef\u4ee5\u4f7f\u7528kebab-case\uff08\u201cmy-app.my-module.foo\u201d\uff09\u4f5c\u4e3a\u524d\u7f00\u8fdb\u884c\u63cf\u8ff0\uff0c<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@Component<\/span>\r\n<span class=\"nd\">@ConfigurationProperties<\/span><span class=\"p\">(<\/span><span class=\"n\">prefix<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"my-app.my-module.foo\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"kd\">data class<\/span> <span class=\"nc\">FooConfig<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">firstName<\/span><span class=\"p\">:<\/span> <span class=\"nc\">String<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">lastName<\/span><span class=\"p\">:<\/span> <span class=\"nc\">String<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">age<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Int<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">0<\/span>\r\n<span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u4f7f\u7528snake-case(&#8220;my_app.my_module.foo&#8221;)\u6216camel-case(&#8220;myApp.myModule.foo&#8221;)\u6765\u7f16\u5199\u4ee3\u7801\uff0c\u5728\u8fd0\u884c\u65f6\u4f1a\u629b\u51fa\u5f02\u5e38\u3002<br \/>\n\u57281.5\u7248\u672c\u4e4b\u524d\uff0c\u4f7f\u7528\u8fd9\u4e9b\u5199\u6cd5\u4e0d\u4f1a\u5f15\u53d1\u5f02\u5e38\uff0c\u4f46\u7531\u4e8e\u5c5e\u6027\u7684\u5199\u6cd5\u4e0d\u7edf\u4e00\uff0c\u65e0\u6cd5\u6309\u9884\u671f\u8fdb\u884c\u7ed1\u5b9a\u3002<\/p>\n<pre class=\"post-pre\"><code>Caused by: org.springframework.boot.context.properties.source.InvalidConfigurationPropertyNameException: Configuration property name 'my_app.my_module.foo' is not valid\r\n<\/code><\/pre>\n<p>\u5728\u8bbe\u7f6e\u5c5e\u6027\u7684\u4e00\u4fa7\uff0c\u4ee5\u4e0b\u8bed\u6cd5\u90fd\u53ef\u4ee5\u8fdb\u884c\u7ed1\u5b9a\u3002<\/p>\n<pre class=\"post-pre\"><code>my-app.my-module.foo.first-name= ruby\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>my_app.my_module.foo.first_name= ruby\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>myApp.myModule.foo.firstName= ruby\r\n<\/code><\/pre>\n<p>\u64cd\u4f5c\u7cfb\u7edf\u73af\u5883\u53d8\u91cf<\/p>\n<pre class=\"post-pre\"><code><span class=\"o\">&gt;<\/span> <span class=\"kd\">SET<\/span> <span class=\"kd\">MY_APP_MY_MODULE_FOO_FIRST_NAME<\/span><span class=\"o\">=<\/span> <span class=\"kd\">ruby<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u8bb0\u6cd5\u6df7\u6742\u7684\u8bdd<\/p>\n<pre class=\"post-pre\"><code>my-app.my-module.foo.first_name= ruby\r\nmy-app.my-module.foo.firstName= ruby\r\nmy-app.my-module.foo.FIRST_NAME= ruby\r\n<\/code><\/pre>\n<p>\u53ea\u9700\u4e00\u79cd\u9009\u9879\uff1a<br \/>\nConditionalOnProperty\u6ce8\u89e3\u7684prefix\u548cname\u5c5e\u6027\u4e5f\u5e94\u4f7f\u7528kebab-case\u6765\u63cf\u8ff0\u3002<br \/>\n\u4f46\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5373\u4f7f\u4f7f\u7528snake-case\u6216camel-case\u8fdb\u884c\u63cf\u8ff0\u4e5f\u4e0d\u4f1a\u5f15\u53d1\u5f02\u5e38\u3002<\/p>\n<pre class=\"post-pre\"><code>@ConditionalOnProperty(prefix = \"my-app.my-module.foo\", name = [\"test-flag\"])\r\n<\/code><\/pre>\n<p>\u987a\u4fbf\u8bf4\u4e00\u53e5\uff0c\u5982\u679c\u60f3\u8981\u5728\u5c5e\u6027\u5177\u6709\u7279\u5b9a\u7684\u503c\u65f6\u8fdb\u884c\u7ed1\u5b9a\uff0c\u53ef\u4ee5\u4f7f\u7528havingValue\u6765\u6307\u5b9a\u6761\u4ef6\u3002<br \/>\n\u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u5f53&#8221;my-app.my-module.foo.test-flag= true&#8221;\u65f6\uff0cBarProperties\u7684\u5bf9\u8c61\u5c06\u88ab\u6ce8\u518c\u5230DI\u5bb9\u5668\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code>@Bean\r\n@ConditionalOnProperty(prefix = \"my-app.my-module.foo\", name = [\"test-flag\"], havingValue = \"true\")\r\nfun bar(foo: FooProperties): BarProperties {\r\n    return BarProperties(foo.name)\r\n}\r\n\r\ndata class BarProperties(val name: String)\r\n<\/code><\/pre>\n<p>\u6b64\u5916\uff0c\u7ed1\u5b9aAPI\u5df2\u8fdb\u884c\u4e86\u4ee5\u4e0b\u4fee\u6539\u3002<\/p>\n<div>\n<div class=\"post-table\">\npackageclassold<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/1.5.10.RELEASE\/api\/org\/springframework\/boot\/bind\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.bind<\/a>RelaxedDataBindernew<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.0.0.RELEASE\/api\/org\/springframework\/boot\/context\/properties\/bind\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.context.properties.bind<\/a>Binder<\/div>\n<\/div>\n<p>\u9664\u5916<\/p>\n<p>\u5c5e\u6027\u4e2d\u5b58\u5728\u7740\u4e00\u4e9b\u7528\u4e8e\u4f20\u9012\u7ed9Spring\u4f7f\u7528\u7684\u800c\u975e\u5185\u7f6e\u5e93\u7684\u5c5e\u6027\u5b9a\u4e49\u3002<br \/>\n\u6bd4\u5982\u4e0b\u9762\u7684spring.jpa.properties.hibernate.*\u5c31\u662f\u4e2a\u4f8b\u5b50\uff0c\u82e5\u4e0d\u6309\u89c4\u5b9a\u7684\u8bed\u6cd5\u6765\u4e66\u5199\uff0c\u5c06\u65e0\u6cd5\u88ab\u8bc6\u522b\u3002<br \/>\n\u4ee5\u8fd9\u4e2a\u4f8b\u5b50\u6765\u8bf4\uff0cname\u90e8\u5206\uff08show_sql\uff09\u5fc5\u987b\u4f7f\u7528\u86c7\u5f62\u547d\u540d\u624d\u80fd\u88ab\u8bc6\u522b\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.jpa.properties.hibernate.show_sql= true\r\n<\/code><\/pre>\n<h4>\u7279\u6027\u79fb\u9664<\/h4>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Remote CRaSH shell<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Spring Loaded<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">Spring Boot CLI\u304b\u3089\u30c6\u30b9\u30c8\u6a5f\u80fd<\/ul>\n<h4>\u66f4\u6539\u5d4c\u5165\u5f0f\u5bb9\u5668\u7684\u8f6f\u4ef6\u5305<\/h4>\n<div>\n<div class=\"post-table\">\npackageinterfaceoldorg.springframework.boot.context.embedded<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/1.5.10.RELEASE\/api\/org\/springframework\/boot\/context\/embedded\/EmbeddedServletContainer.html\" target=\"_blank\" rel=\"nofollow noopener\">EmbeddedServletContainer<\/a>neworg.springframework.boot.web.serverWebServer<\/div>\n<\/div>\n<p>\u7801\u5934<\/p>\n<div>\n<div class=\"post-table\">\npackageclassold<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/1.5.10.RELEASE\/api\/org\/springframework\/boot\/context\/embedded\/jetty\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.context.embedded.jetty<\/a>JettyEmbeddedServletContainerFactorynew<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.0.0.RELEASE\/api\/org\/springframework\/boot\/web\/embedded\/jetty\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.web.embedded.jetty<\/a>JettyServletWebServerFactory<\/p>\n<p>JettyReactiveWebServerFactory<\/p><\/div>\n<\/div>\n<p>Tomcat \u7ffb\u8bd1\u6210\u4e2d\u6587\u5c31\u662f\u732b\u5934\u9e70\u3002<\/p>\n<div>\n<div class=\"post-table\">\npackageclassold<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/1.5.10.RELEASE\/api\/org\/springframework\/boot\/context\/embedded\/tomcat\/TomcatEmbeddedServletContainerFactory.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.context.embedded.tomcat<\/a>TomcatEmbeddedServletContainerFactorynew<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.0.0.RELEASE\/api\/org\/springframework\/boot\/web\/embedded\/tomcat\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.web.embedded.tomcat<\/a>TomcatServletWebServerFactory<\/p>\n<p>TomcatReactiveWebServerFactory<\/p><\/div>\n<\/div>\n<p>\u88ab\u6c34\u6d41\u5e26\u8d70<\/p>\n<div>\n<div class=\"post-table\">\npackageclassold<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/1.5.10.RELEASE\/api\/org\/springframework\/boot\/context\/embedded\/undertow\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.context.embedded.undertow<\/a>UndertowEmbeddedServletContainerFactorynew<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.0.0.RELEASE\/api\/org\/springframework\/boot\/web\/embedded\/undertow\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.web.embedded.undertow<\/a>UndertowServletWebServerFactory<\/p>\n<p>UndertowReactiveWebServerFactory<\/p><\/div>\n<\/div>\n<p>Netty\uff08\u88dc\u5145\uff09<\/p>\n<ul class=\"post-ul\">Netty\u306f2.0\u304b\u3089\u8ffd\u52a0\u3055\u308c\u305fWebFlux\u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u306eengine\u3067\u3059\u3002<\/ul>\n<div>\n<div class=\"post-table\">\npackageclassnew<a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.0.0.RELEASE\/api\/org\/springframework\/boot\/web\/embedded\/netty\/package-summary.html\" target=\"_blank\" rel=\"nofollow noopener\">org.springframework.boot.web.embedded.netty<\/a>NettyReactiveWebServerFactory<\/div>\n<\/div>\n<h4>\u2605\u66f4\u6539\u9ed8\u8ba4\u7684\u6570\u636e\u6e90<\/h4>\n<p>\u9ed8\u8ba4\u7684\u6570\u636e\u6e90\u5df2\u4eceTomcat\u66f4\u6539\u4e3aHikariCP\u3002<\/p>\n<h5>HikariCP \u5149\u534e\u8fde\u63a5\u6c60<\/h5>\n<p>\u5982\u679c\u660e\u786e\u6307\u5b9a\u7684\u8bdd<\/p>\n<p>\u7531\u4e8e\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u4e0d\u9700\u8981\u660e\u786e\u6307\u5b9a\uff0c\u4f46\u662f\u5982\u679c\u8981\u5199\u7684\u8bdd\uff0c\u53ef\u4ee5\u6309\u7167\u4ee5\u4e0b\u65b9\u5f0f\u6765\u5199\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.datasource.type<\/span><span class=\"p\">=<\/span> <span class=\"s\">com.zaxxer.hikari.HikariDataSource<\/span>\r\n<\/code><\/pre>\n<p>HikariCP\u7684\u5c5e\u6027\u8bbe\u7f6e<\/p>\n<pre class=\"post-pre\"><code>spring.datasource.hikari.*\r\n<\/code><\/pre>\n<div>\n<div class=\"post-table\">property nametypedefaultallow-pool-suspensionBooleanfalseauto-commitBooleantruecatalogStringdriver defaultconnection-init-sqlStringnoneconnection-test-queryStringnoneconnection-timeoutLong30000 msdata-source-class-nameStringnonedata-source-j-n-d-iString<br \/>\ndata-source-propertiesMap<br \/>\ndriver-class-nameStringnonehealth-check-propertiesMap<br \/>\nhealth-check-registryObjectnone (HikariCP 2.3.2+ supports Dropwizard HealthChecks.)idle-timeoutLong600000 msinitialization-fail-timeoutLong1 sisolate-internal-queriesBooleanfalsejdbc-urlStringnoneleak-detection-thresholdLong0 mslogin-timeoutInteger(official\u306b\u8a18\u8f09\u306a\u3057)max-lifetimeLong1800000 msmaximum-pool-sizeInteger10metric-registryObjectnonemetrics-tracker-factoryFactory(official\u306b\u8a18\u8f09\u306a\u3057)minimum-idleIntegersame as maximumPoolSizepasswordStringnonepool-nameStringauto-generatedread-onlyBooleanfalseregister-mbeansBooleanfalsescheduled-executorservicenoneschemaStringdriver defaulttransaction-isolationStringdriver defaultusernameStringnonevalidation-timeoutLong5000ms<\/div>\n<\/div>\n<h5>\u6c64\u59c6\u732b<\/h5>\n<p>\u5982\u679c\u60f3\u8981\u6062\u590d\u5230Tomcat\u7684\u8bdd<\/p>\n<p>Maven (\u4e00\u79cd\u5de5\u5177)<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;dependency&gt;<\/span>\r\n    <span class=\"nt\">&lt;groupId&gt;<\/span>org.springframework.boot<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n    <span class=\"nt\">&lt;artifactId&gt;<\/span>spring-boot-starter-data-jpa<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n    <span class=\"nt\">&lt;exclusions&gt;<\/span>\r\n        <span class=\"nt\">&lt;exclusion&gt;<\/span>\r\n            <span class=\"nt\">&lt;groupId&gt;<\/span>com.zaxxer<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n            <span class=\"nt\">&lt;artifactId&gt;<\/span>HikariCP<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n        <span class=\"nt\">&lt;\/exclusion&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/exclusions&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<span class=\"nt\">&lt;dependency&gt;<\/span>\r\n    <span class=\"nt\">&lt;groupId&gt;<\/span>org.apache.tomcat<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n    <span class=\"nt\">&lt;artifactId&gt;<\/span>tomcat-jdbc<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<\/code><\/pre>\n<p>Gradle (\u683c\u96f7\u5fb7)<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-starter-data-jpa\"<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">exclude<\/span> <span class=\"nl\">group:<\/span> <span class=\"s2\">\"com.zaxxer\"<\/span><span class=\"o\">,<\/span> <span class=\"nl\">module:<\/span> <span class=\"s2\">\"HikariCP\"<\/span>\r\n<span class=\"o\">}<\/span>\r\n<span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.apache.tomcat:tomcat-jdbc\"<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<p>\u8986\u76d6\u9ed8\u8ba4\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.datasource.type<\/span><span class=\"p\">=<\/span> <span class=\"s\">org.apache.tomcat.jdbc.pool.DataSource<\/span>\r\n<\/code><\/pre>\n<p>Tomcat\u8fde\u63a5\u6c60\u7684\u5c5e\u6027\u8bbe\u7f6e<\/p>\n<pre class=\"post-pre\"><code>spring.datasource.tomcat.*\r\n<\/code><\/pre>\n<p>\u5e38\u89c1\u7684\u7279\u70b9<\/p>\n<div>\n<div class=\"post-table\">property nametypedefaultdefaultAutoCommitbooleanJDBC driver defaultdefaultReadOnlyboolean<br \/>\ndefaultTransactionIsolationStringJDBC driver defaultdefaultCatalogString<br \/>\ndriverClassNameString<br \/>\nusernameString<br \/>\npasswordString<br \/>\nmaxActiveint100maxIdleintsame as maxActiveminIdleintsame as initialSizeinitialSizeint10maxWaitint30000 mstestOnBorrowbooleanfalsetestOnConnectbooleanfalsetestOnReturnbooleanfalsetestWhileIdlebooleanfalsevalidationQueryString<br \/>\nvalidationQueryTimeoutint-1validatorClassNameStringnulltimeBetweenEvictionRunsMillisint5000 msnumTestsPerEvictionRunint*Property not usedminEvictableIdleTimeMillisint60000 msaccessToUnderlyingConnectionAllowedboolean<br \/>\nremoveAbandonedbooleanfalseremoveAbandonedTimeoutint60 slogAbandonedbooleanfalseconnectionPropertiesStringnullpoolPreparedStatementsboolean*Property not usedmaxOpenPreparedStatementsint*Property not used<\/div>\n<\/div>\n<ul class=\"post-ul\">Tomcat JDBC Enhanced Attributes\u306f\u5272\u611b\u3057\u307e\u3059\u3002<\/ul>\n<h4>\u5220\u9664\u5bf9spring-boot-starter-web\u7684\u4f9d\u8d56\u3002<\/h4>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">spring-boot-starter-mustache<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">spring-boot-starter-thymeleaf<\/ul>\n<p>\u8fd9\u4e9bstarter\u7684\u4f9d\u8d56\u5173\u7cfb\u5df2\u4ecespring-boot-starter-web\u4e2d\u5220\u9664\u3002<br \/>\n\u5177\u4f53\u800c\u8a00\uff0cpom.xml\u6587\u4ef6\u4e2d\u7684\u4f9d\u8d56\u5173\u7cfb\u5df2\u88ab\u5220\u9664\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;dependency&gt;<\/span>\r\n    <span class=\"nt\">&lt;groupId&gt;<\/span>org.springframework.boot<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n    <span class=\"nt\">&lt;artifactId&gt;<\/span>spring-boot-starter-web<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<\/code><\/pre>\n<h4>WebFlux\u7684\u652f\u6301<\/h4>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">spring-boot-starter-webflux<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">spring-boot-starter-reactor-netty (default web engine)<\/ul>\n<h4>\u5bf9\u4e8e\u54cd\u5e94\u5f0f\u6570\u636e\u7684\u652f\u6301<\/h4>\n<p>\u65b0\u589e\u4e86\u4e00\u79cd\u80fd\u591f\u8fdb\u884c\u53cd\u5e94\u6027\u5904\u7406\u7684\u6570\u636e\u5b58\u50a8\u5e93\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">MongoDB (spring-boot-starter-data-mongodb-reactive)<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Redis (spring-boot-starter-data-redis-reactive)<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">Cassandra (spring-boot-starter-data-cassandra-reactive)<\/ul>\n<h4>\u4ee3\u7406\u7b56\u7565\u7684\u9ed8\u8ba4\u66f4\u6539<\/h4>\n<p>\u9ed8\u8ba4\u503c\u5df2\u66f4\u6539\u4e3aCGLIB\u3002\u60a8\u53ef\u4ee5\u901a\u8fc7\u66f4\u6539proxy-target-class\u5c5e\u6027\u8fdb\u884c\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.aop.proxy-target-class<\/span><span class=\"p\">=<\/span> <span class=\"s\">true<\/span>\r\n<\/code><\/pre>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">true : CGLIB subclass-based<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">false : JDK interface-based<\/ul>\n<h4>\u66f4\u6539application.properties\u7684\u547d\u540d\u7a7a\u95f4<\/h4>\n<p>Servlet\u7684\u7279\u5b9a\u670d\u52a1\u5668\u5c5e\u6027<\/p>\n<div>\n<div class=\"post-table\">oldnewserver.context-parameters.*server.servlet.context-parameters.*server.context-pathserver.servlet.context-pathserver.jsp.init-parameters.*server.servlet.jsp.init-parameters.*server.jsp.registeredserver.servlet.jsp.registeredserver.pathserver.servlet.path<\/div>\n<\/div>\n<p>\u591a\u90e8\u5206\u914d\u7f6e<\/p>\n<div>\n<div class=\"post-table\">oldnewspring.http.multipart.*spring.servlet.multipart.*<\/div>\n<\/div>\n<h4>\u66f4\u6539webEnvironment\u6807\u5fd7\u7684\u6307\u5b9a\u65b9\u6cd5<\/h4>\n<p>\u7531\u4e8e\u6dfb\u52a0\u4e86WebFlux\uff0c\u65b0\u589e\u4e86\u4e00\u4e2a\u540d\u4e3aspring.main.web-application-type\u7684\u65b0\u5c5e\u6027\u3002<\/p>\n<p>\u5728Spring Boot 1.5\u4e4b\u524d\u7684\u7248\u672c\u4e2d\uff0c\u5982\u679c\u4e0d\u60f3\u5c06\u5176\u4f5c\u4e3aweb\u5e94\u7528\u7a0b\u5e8f\u542f\u52a8\uff08\u5373\u4e0d\u542f\u52a8\u5185\u5d4c\u7684web\u5bb9\u5668\uff09\uff0c\u53ef\u4ee5\u8fdb\u884c\u4ee5\u4e0b\u914d\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.main.web-environment<\/span><span class=\"p\">=<\/span> <span class=\"s\">false<\/span>\r\n<\/code><\/pre>\n<p>\u4ece2.0\u7248\u672c\u5f00\u59cb\uff0c\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e\u65b0\u7684\u5c5e\u6027spring.main.web-application-type\u4e3anone\u6765\u6307\u5b9a\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.main.web-application-type<\/span><span class=\"p\">=<\/span> <span class=\"s\">none<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u53ef\u4ee5\u6307\u5b9a\u7684\u503c\u6709\u4e09\u79cd\u7c7b\u578b\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">none<\/ul>\n<\/li>\n<\/ul>\n<p>The application should not run as a web application and should not start an embedded web server<\/p>\n<p>servlet<\/p>\n<p>The application should run as a servlet-based web application and should start an embedded servlet web server.<\/p>\n<p>reactive<\/p>\n<p>The application should run as a reactive web application and should start an embedded reactive web server.<\/p>\n<h4>\u66f4\u6539Mustache\u6a21\u677f\u7684\u9ed8\u8ba4\u503c<\/h4>\n<p>Mustache\u6a21\u677f\u5f15\u64ce\u7684\u6a21\u677f\u6587\u4ef6\u9ed8\u8ba4\u6269\u5c55\u540d\u5df2\u4ece.html\u66f4\u6539\u4e3a.mustache\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.mustache.suffix<\/span><span class=\"p\">=<\/span> <span class=\"s\">.mustache<\/span>\r\n<\/code><\/pre>\n<h4>\u2605 Gradle\u63d2\u4ef6\u7684\u53d8\u66f4<\/h4>\n<p>\u6b63\u5982\u8fd9\u7bc7\u535a\u5ba2\uff08Spring Boot\u7684\u65b0Gradle\u63d2\u4ef6\uff09\u6240\u53d1\u5e03\u7684\u90a3\u6837\uff0cGradle\u63d2\u4ef6\u7684\u529f\u80fd\u5df2\u7ecf\u53d1\u751f\u4e86\u53d8\u5316\u3002<\/p>\n<h5>\u751f\u6210\u53ef\u4ee5\u8fd0\u884c\u7684jar\/war\u6587\u4ef6<\/h5>\n<p>\u751f\u6210\u53ef\u6267\u884c\u7684JAR\u6216WAR\u6587\u4ef6\uff0c\u901a\u5e38\u4f7f\u7528bootRepackage\u4efb\u52a1\u6765\u5b8c\u6210\uff0c\u4f46\u73b0\u5728\u5df2\u88ab\u66ff\u6362\u4e3abootJar\u6216bootWar\u4efb\u52a1\u3002<\/p>\n<h5>\u4f9d\u8d56\u7ba1\u7406\u63d2\u4ef6<\/h5>\n<p>\u9700\u8981\u660e\u786e\u5730\u5c06\u8d1f\u8d23\u5904\u7406\u4f9d\u8d56\u5173\u7cfb\u7ba1\u7406\u7684dependency-management-plugin\u6dfb\u52a0\u5230\u9879\u76ee\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">apply<\/span> <span class=\"nl\">plugin:<\/span> <span class=\"s1\">'io.spring.dependency-management'<\/span>\r\n<\/code><\/pre>\n<h3>Spring-Boot-2.0.0-M2-\u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 M2 Configuration Changelog<\/ul>\n<h4>\u6dfb\u52a0spring-boot-starter-quartz<\/h4>\n<p>\u6709\u4e00\u6b3e\u540d\u4e3aQuartz Job Scheduler\u7684\u4f5c\u4e1a\u8c03\u5ea6\u5668\u5df2\u4f5c\u4e3aspring-boot-starter\u5f97\u5230\u652f\u6301\u3002<\/p>\n<h4>\u6625\u5929\u7684\u6570\u636e\u7f51\u7edc\u914d\u7f6e<\/h4>\n<p>\u5728application.properties\u6587\u4ef6\u4e2d\uff0c\u53ef\u4ee5\u8fdb\u884c\u5206\u9875\u548c\u6392\u5e8f\u7684\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># SpringDataWebProperties\r\n<\/span><span class=\"py\">spring.data.web.pageable.default-page-size<\/span><span class=\"p\">=<\/span> <span class=\"s\">20<\/span>\r\n<span class=\"py\">spring.data.web.pageable.max-page-size<\/span><span class=\"p\">=<\/span> <span class=\"s\">2000<\/span>\r\n<span class=\"c\"># Whether to expose and assume 1-based page number indexes.\r\n<\/span><span class=\"py\">spring.data.web.pageable.one-indexed-parameters<\/span><span class=\"p\">=<\/span> <span class=\"s\">false<\/span>\r\n<span class=\"py\">spring.data.web.pageable.page-parameter<\/span><span class=\"p\">=<\/span> <span class=\"s\">page<\/span>\r\n<span class=\"c\"># General prefix to be prepended to the page number and page size parameters.\r\n<\/span><span class=\"py\">spring.data.web.pageable.prefix<\/span><span class=\"p\">=<\/span> <span class=\"s\">\"\"<\/span>\r\n<span class=\"c\"># Delimiter to be used between the qualifier and the actual page number and size properties.\r\n<\/span><span class=\"py\">spring.data.web.pageable.qualifier-delimiter<\/span><span class=\"p\">=<\/span> <span class=\"s\">_<\/span>\r\n<span class=\"py\">spring.data.web.pageable.size-parameter<\/span><span class=\"p\">=<\/span> <span class=\"s\">size<\/span>\r\n<span class=\"py\">spring.data.web.sort.sort-parameter<\/span><span class=\"p\">=<\/span> <span class=\"s\">sort<\/span>\r\n<\/code><\/pre>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">prefix<\/ul>\n<\/li>\n<\/ul>\n<p>\u5404\u30d1\u30e9\u30e1\u30fc\u30bf\u306eprefix\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002<br \/>\n\u4f8b) prefix=p_ \u2192 \u30d1\u30e9\u30e1\u30fc\u30bf\u540d\u306fp_page\u3084p_size\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>one-indexed-parameters<\/p>\n<p>false\u3001\u30da\u30fc\u30b8\u756a\u53f7\u306e\u59cb\u307e\u308a\u30920\u3068\u3057\u307e\u3059\u3002<\/p>\n<p>page=0\u306f1\u30da\u30fc\u30b8\u76ee\u3001page=1\u306f2\u30da\u30fc\u30b8\u76ee\u3092\u6307\u3057\u307e\u3059\u3002<\/p>\n<p>true\u3001\u30da\u30fc\u30b8\u756a\u53f7\u306e\u59cb\u307e\u308a\u30921\u3068\u3057\u307e\u3059\u3002<\/p>\n<p>page=0\u3068page=1\u306f\u540c\u30581\u30da\u30fc\u30b8\u76ee\u3001page=2\u306f2\u30da\u30fc\u30b8\u76ee\u3092\u6307\u3057\u307e\u3059\u3002<\/p>\n<p>qualifier-delimiter<\/p>\n<p>qualifier\u3068\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u533a\u5207\u308a\u6587\u5b57\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002<br \/>\n1\u3064\u306eURL\u306b2\u3064(\u4ee5\u4e0a)\u306e\u30da\u30fc\u30b8\u60c5\u5831\u3092\u542b\u3081\u305f\u3044\u5834\u5408\u306b\u5229\u7528\u3057\u307e\u3059\u3002<\/p>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u5c06\u4f1a\u6620\u5c04\u5230SpringDataWebProperties\u7c7b\u4e2d\u3002<\/p>\n<p>\u793a\u4f8b\u4ee3\u7801<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.data.domain.Pageable<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.web.bind.annotation.GetMapping<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.web.bind.annotation.RequestMapping<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nn\">org.springframework.web.bind.annotation.RestController<\/span>\r\n\r\n<span class=\"nd\">@RestController<\/span>\r\n<span class=\"nd\">@RequestMapping<\/span><span class=\"p\">(<\/span><span class=\"n\">path<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"index\"<\/span><span class=\"p\">])<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">IndexController<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"c1\">\/\/ \u4f8b1<\/span>\r\n    <span class=\"nd\">@GetMapping<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">index<\/span><span class=\"p\">(<\/span><span class=\"n\">pageable<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Pageable<\/span><span class=\"p\">):<\/span> <span class=\"nc\">String<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">pageable<\/span><span class=\"p\">.<\/span><span class=\"nf\">toString<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"c1\">\/\/ \u4f8b2<\/span>\r\n    <span class=\"nd\">@GetMapping<\/span><span class=\"p\">(<\/span><span class=\"n\">path<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"2\"<\/span><span class=\"p\">])<\/span>\r\n    <span class=\"k\">fun<\/span> <span class=\"nf\">index2<\/span><span class=\"p\">(<\/span><span class=\"nd\">@Qualifier<\/span><span class=\"p\">(<\/span><span class=\"s\">\"foo\"<\/span><span class=\"p\">)<\/span> <span class=\"n\">foo<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Pageable<\/span>\r\n             <span class=\"p\">,<\/span> <span class=\"nd\">@Qualifier<\/span><span class=\"p\">(<\/span><span class=\"s\">\"bar\"<\/span><span class=\"p\">)<\/span> <span class=\"n\">bar<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Pageable<\/span><span class=\"p\">):<\/span> <span class=\"nc\">String<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nf\">println<\/span><span class=\"p\">(<\/span><span class=\"s\">\"foo: ${foo}\"<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">println<\/span><span class=\"p\">(<\/span><span class=\"s\">\"bar: ${bar}\"<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"s\">\"OK\"<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4f8b1\uff1a\u6211\u6628\u5929\u53bb\u4e86\u4e00\u4e2a\u65b0\u7684\u5496\u5561\u9986\uff0c\u91cc\u9762\u7684\u5496\u5561\u975e\u5e38\u597d\u559d\u3002<\/p>\n<pre class=\"post-pre\"><code>http:\/\/localhost:9000\/app\/index\r\n\r\n\u3000\u3000\u3000\u2193\r\n\r\nPage request [number: 0, size 20, sort: UNSORTED]\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>http:\/\/localhost:9000\/app\/index?page=1&amp;size=30&amp;sort=id,desc&amp;sort=name,asc\r\n\r\n\u3000\u3000\u3000\u2193\r\n\r\nPage request [number: 1, size 30, sort: id: DESC,name: ASC]\r\n<\/code><\/pre>\n<p>\u4ee5\u4e0b\u662f\u82f1\u6587\u53e5\u5b50\u300c\u4f8b2\u300d\u7684\u4e2d\u6587\u91ca\u4e49\uff1a<\/p>\n<pre class=\"post-pre\"><code>http:\/\/localhost:9000\/app\/index\/2?foo_page=1&amp;foo_size=10&amp;bar_page=3&amp;bar_size=10\r\n\r\n\u3000\u3000\u3000\u2193\r\n\r\nfoo: Page request [number: 1, size 10, sort: UNSORTED]\r\nbar: Page request [number: 3, size 10, sort: UNSORTED]\r\n<\/code><\/pre>\n<p>\u8bf7\u6ce8\u610f\u3002<\/p>\n<p>\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u6709\u7c7b\u4f3c\u4e8eSpring Data Rest\u7684\u53c2\u6570\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># DATA REST (RepositoryRestProperties)\r\n<\/span><span class=\"py\">spring.data.rest.default-page-size<\/span><span class=\"p\">=<\/span> <span class=\"c\"># Default size of pages.\r\n<\/span><span class=\"s\">spring.data.rest.limit-param-name= # Name of the URL query string parameter that indicates how many results to return at once.<\/span>\r\n<span class=\"py\">spring.data.rest.max-page-size<\/span><span class=\"p\">=<\/span> <span class=\"c\"># Maximum size of pages.\r\n<\/span><span class=\"s\">spring.data.rest.page-param-name= # Name of the URL query string parameter that indicates what page to return.<\/span>\r\n<span class=\"py\">spring.data.rest.sort-param-name<\/span><span class=\"p\">=<\/span> <span class=\"c\"># Name of the URL query string parameter that indicates what direction to sort results.\r\n<\/span><\/code><\/pre>\n<h4>JDBCTemplate \u914d\u7f6e<\/h4>\n<p>JDBCTemplate\u7684\u8bbe\u7f6e\u73b0\u5728\u53ef\u4ee5\u5728application.properties\u4e2d\u5b8c\u6210\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.jdbc.template.fetch-size<\/span><span class=\"p\">=<\/span> <span class=\"s\">-1<\/span>\r\n<span class=\"py\">spring.jdbc.template.max-rows<\/span><span class=\"p\">=<\/span> <span class=\"s\">-1<\/span>\r\n<span class=\"py\">spring.jdbc.template.query-timeout<\/span><span class=\"p\">=<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u5c06\u4f1a\u53cd\u6620\u5728 JdbcProperties \u7c7b\u4e2d\u3002<\/p>\n<h4>Cassandra\u7684\u8fde\u63a5\u6c60\u9009\u9879\u8bbe\u7f6e\u3002<\/h4>\n<p>\u5728application.properties\u6587\u4ef6\u4e2d\uff0c\u53ef\u4ee5\u8fdb\u884c\u6c60\u5316\u9009\u9879\u7684\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.data.cassandra.pool.heartbeat-interval<\/span><span class=\"p\">=<\/span> <span class=\"s\">30s<\/span>\r\n<span class=\"py\">spring.data.cassandra.pool.idle-timeout<\/span><span class=\"p\">=<\/span> <span class=\"s\">120s<\/span>\r\n<span class=\"py\">spring.data.cassandra.pool.max-queue-size<\/span><span class=\"p\">=<\/span> <span class=\"s\">256<\/span>\r\n<span class=\"py\">spring.data.cassandra.pool.pool-timeout<\/span><span class=\"p\">=<\/span> <span class=\"s\">5000ms<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u5c06\u6620\u5c04\u5230CassandraProperties\u7c7b\u4e2d\u3002<\/p>\n<h4>\u6dfb\u52a0spring-boot-starter-json<\/h4>\n<p>\u6709\u4e86\u66ff\u4ee3Jackson-databind\u7684spring-boot-starter-json\u7684\u65b0\u589e\u529f\u80fd\u3002<\/p>\n<p>Maven (\u4e00\u79cd\u8f6f\u4ef6\u7ba1\u7406\u5de5\u5177)<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;dependency&gt;<\/span>\r\n    <span class=\"nt\">&lt;groupId&gt;<\/span>org.springframework.boot<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n    <span class=\"nt\">&lt;artifactId&gt;<\/span>spring-boot-starter-json<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<\/code><\/pre>\n<p>Gradle\uff1a\u683c\u96f7\u5fb7<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-starter-json\"<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<p>\u800c\u4e14\uff0c\u4e0d\u518d\u9700\u8981\u53e6\u5916\u6dfb\u52a0\u4ee5\u4e0b\u7684\u4f9d\u8d56\u5173\u7cfb\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">jackson-datatype-jdk8<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">jackson-datatype-jsr310<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">jackson-module-parameter-names<\/ul>\n<h4>\u66f4\u6539spring-boot-starter-thymeleaf\u7684\u5185\u5bb9\u3002<\/h4>\n<p>\u7531\u4e8espring-boot-starter-thymeleaf\u73b0\u5728\u5305\u542b\u4e86\u5bf9thymeleaf-extras-java8time\u7684\u4f20\u9012\u4f9d\u8d56\u5173\u7cfb\uff0c\u56e0\u6b64\u4e0d\u9700\u8981\u518d\u5355\u72ec\u6dfb\u52a0\u4f9d\u8d56\u5173\u7cfb\u4e86\u3002<\/p>\n<h4>Mongo\u5ba2\u6237\u7aef\u7684\u914d\u7f6e<\/h4>\n<p>\u53ef\u4ee5\u4f7f\u7528MongoClientSettingsBuilderCustomizer\u6765\u5bf9Mongo\u5ba2\u6237\u7aef\u8fdb\u884c\u914d\u7f6e\u3002<\/p>\n<h4>\u6d4b\u8bd5<\/h4>\n<p>\u5df2\u6dfb\u52a0\u4e86\u7528\u4e8e\u5355\u5143\u6d4b\u8bd5\u7684\u6ce8\u89e3\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">JooqTest<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">DataRedisTest<\/ul>\n<h3>Spring-Boot-2.0.0-M3\u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 M3 Configuration Changelog<\/ul>\n<h4>\u2605Maven\u63d2\u4ef6\u7684\u66f4\u6539<\/h4>\n<p>\u5982\u679c\u8981\u5728\u76ee\u6807\u4e2d\u6307\u5b9a\u53c2\u6570\uff0c\u901a\u5e38\u4f1a\u5728\u53c2\u6570\u540d\u79f0\u7684\u524d\u7f00\u52a0\u4e0a&#8221;spring-boot&#8221;\u3002<\/p>\n<p>\u4ee5\u4e0b\u662f\u4e00\u4e2a\u4f8b\u5b50\u3002<\/p>\n<p>Please provide the sentence that needs to be paraphrased.<\/p>\n<p>\u76f4\u52301.5\u7248\u672c\uff0c\u7528\u4e8e\u6307\u5b9a\u914d\u7f6e\u6587\u4ef6\u7684\u53c2\u6570\u662frun.profiles\u3002<\/p>\n<pre class=\"post-pre\"><code>mvn spring-boot:run -Drun.profiles=foo\r\n<\/code><\/pre>\n<p>2.0\u7248\u672c\u53ca\u4ee5\u540e\u4f1a\u5c06\u5176\u66f4\u6539\u4e3aspring-boot.run.profiles\u3002<\/p>\n<pre class=\"post-pre\"><code>mvn spring-boot:run -Dspring-boot.run.profiles=foo\r\n<\/code><\/pre>\n<h4>\u5f00\u53d1\u5de5\u5177\u7684\u66f4\u6539<\/h4>\n<p>\u4e0d\u518d\u652f\u6301\u901a\u8fc7HTTP\u8fdb\u884c\u8fdc\u7a0b\u8c03\u8bd5\u3002<\/p>\n<h3>Spring-Boot-2.0.0-M4\u7248\u672c\u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 M4 Configuration Changelog<\/ul>\n<h4>\u66f4\u6539application.properties\u7684\u547d\u540d\u7a7a\u95f4<\/h4>\n<p>Liquibase\u548cFlyway<\/p>\n<div>\n<div class=\"post-table\">oldnewliquibase.*spring.liquibase.*flyway.*spring.flyway.*<\/div>\n<\/div>\n<h4>\u6570\u636e\u5e93\u521d\u59cb\u5316\u7a0b\u5e8f<\/h4>\n<p>Spring Batch\u4f7f\u7528\u7684\u6570\u636e\u5e93\u521d\u59cb\u5316\u63a7\u5236\u5c5e\u6027\u5df2\u7ecf\u53d1\u751f\u4e86\u53d8\u5316\u3002\u6b64\u5916\uff0cSpring Integration\u3001Spring Session\u548cQUARTZ SCHEDULER\u4e5f\u53ef\u4ee5\u901a\u8fc7\u7c7b\u4f3c\u7684\u673a\u5236\u8fdb\u884c\u521d\u59cb\u5316\u3002<\/p>\n<p>\u53ef\u4ee5\u6307\u5b9a\u7684\u503c\u662f\u6839\u636eDataSourceInitializationMode\u5b9a\u4e49\u7684\u4e09\u79cd\u7c7b\u578b\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">always<\/ul>\n<\/li>\n<\/ul>\n<p>Always initialize the datasource.<\/p>\n<p>embedded<\/p>\n<p>Only initialize an embedded datasource.<\/p>\n<p>never<\/p>\n<p>Do not initialize the datasource.<\/p>\n<p>\u6625\u5b63\u6279\u5904\u7406<\/p>\n<pre class=\"post-pre\"><code>spring.batch.initializer.enabled= true\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>spring.batch.initialize-schema= embedded\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u4f1a\u53cd\u6620\u5728BatchProperties\u7c7b\u4e2d\u3002<\/p>\n<p>\u6625\u5929\u878d\u5408<\/p>\n<pre class=\"post-pre\"><code>spring.integration.jdbc.initialize-schema= embedded\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u5c06\u53cd\u6620\u5728Class IntegrationProperties\u4e2d\u3002<\/p>\n<p>\u6625\u5b63\u4f1a\u8bae<\/p>\n<pre class=\"post-pre\"><code>spring.session.jdbc.initialize-schema=embedded\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u5c06\u4f1a\u5728Class JdbcSessionProperties\u4e2d\u4f53\u73b0\u3002<\/p>\n<p>\u77f3\u82f1\u8c03\u5ea6\u5668<\/p>\n<pre class=\"post-pre\"><code>spring.quartz.jdbc.initialize-schema= embedded\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u4f1a\u88ab\u53cd\u6620\u5728\u7c7bQuartzProperties\u4e2d\u3002<\/p>\n<h4>\u7f16\u8bd1\u6807\u5fd7<\/h4>\n<p>\u5728\u4f7f\u7528Spring Boot\u7684Maven\u9879\u76ee\u4e2d\uff0c-parameters\u7f16\u8bd1\u6807\u5fd7\u9ed8\u8ba4\u662f\u542f\u7528\u7684\u3002<\/p>\n<blockquote><p>\u4e3a\u4e86\u80fd\u591f\u83b7\u53d6Reflection API\u7684\u65b9\u6cd5java.lang.reflect.Executable.getParameters\u7684\u53c2\u6570\uff0c\u5c06\u6784\u9020\u51fd\u6570\u548c\u65b9\u6cd5\u7684\u865a\u62df\u53c2\u6570\u540d\u79f0\u5b58\u50a8\u5728\u751f\u6210\u7684\u7c7b\u6587\u4ef6\u4e2d\u3002<\/p><\/blockquote>\n<h4>\u2605\u652f\u6301<\/h4>\n<ul class=\"post-ul\">Java9<\/ul>\n<h3>Spring Boot 2.0.0 M5 \u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 M5 Configuration Changelog<\/ul>\n<h4>Maven Surefire\u63d2\u4ef6\u7684\u5347\u7ea7\u7248\u672c\u3002<\/h4>\n<p>Maven Surefire\u63d2\u4ef6\u7684include\/exclude\u8bbe\u7f6e\u5df2\u88ab\u66f4\u6539\u3002<br \/>\n\u4e0b\u9762\u662f\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u9002\u7528\u4e8e1.5\u7248\u672c\u3002\u57282.0\u7248\u672c\u4e2d\uff0c\u4f7f\u7528\u7684Surefire\u63d2\u4ef6\u7248\u672c\u5df2\u7ecf\u5347\u7ea7\uff0c\u5e76\u4e14\u9ed8\u8ba4\u8bbe\u7f6e\u4e5f\u53d1\u751f\u4e86\u6539\u53d8\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;plugin&gt;<\/span>\r\n    <span class=\"nt\">&lt;groupId&gt;<\/span>org.apache.maven.plugins<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n    <span class=\"nt\">&lt;artifactId&gt;<\/span>maven-surefire-plugin<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n    <span class=\"nt\">&lt;configuration&gt;<\/span>\r\n        <span class=\"nt\">&lt;includes&gt;<\/span>\r\n             <span class=\"nt\">&lt;include&gt;<\/span>**\/*Tests.java<span class=\"nt\">&lt;\/include&gt;<\/span>\r\n             <span class=\"nt\">&lt;include&gt;<\/span>**\/*Test.java<span class=\"nt\">&lt;\/include&gt;<\/span>\r\n        <span class=\"nt\">&lt;\/includes&gt;<\/span>\r\n        <span class=\"nt\">&lt;excludes&gt;<\/span>\r\n            <span class=\"nt\">&lt;exclude&gt;<\/span>**\/Abstract*.java<span class=\"nt\">&lt;\/exclude&gt;<\/span>\r\n        <span class=\"nt\">&lt;\/excludes&gt;<\/span>\r\n    <span class=\"nt\">&lt;\/configuration&gt;<\/span>\r\n<span class=\"nt\">&lt;\/plugin&gt;<\/span>\r\n<\/code><\/pre>\n<p>\u53e6\u5916\uff0c\u5982\u679c\u8981\u4f7f\u7528JUnit5\uff0c\u5219\u9700\u8981\u5c06\u4f7f\u7528\u7684Maven Surefire\u63d2\u4ef6\u7248\u672c\u964d\u4f4e\u81f32.19.1\u3002<\/p>\n<ul class=\"post-ul\">Inclusions and Exclusions of Tests<\/ul>\n<p>\u63d2\u4ef6\u7248\u672c\u7684\u5f53\u524d\u72b6\u6001<\/p>\n<p>\u6211\u6574\u7406\u4e86\u9ed8\u8ba4\u4f7f\u7528\u7684\u63d2\u4ef6\u7248\u672c\u3002<\/p>\n<div>\n<div class=\"post-table\">plugin1.5.102.0.0.RC2clean2.6.13.0.0 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>compiler3.13.7.0 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>deploy2.8.22.8.2install2.5.22.5.2jar2.63.0.2 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>resources2.63.0.1 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>site3.5.13.6 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>surefire2.18.12.20.1 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>spring-boot1.5.102.0.0 <img loading=\"lazy\" decoding=\"async\" class=\"emoji\" title=\":arrow_up:\" src=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" alt=\":arrow_up:\" width=\"20\" height=\"20\" \/>build-helper1.10-help2.2-xml1.0-<\/div>\n<\/div>\n<h4>Gradle\u63d2\u4ef6\u7684\u4fee\u6539<\/h4>\n<p>\u5728bootRun\u4efb\u52a1\u4e2d\uff0c\u53ef\u4ee5\u6307\u5b9a\u5e94\u7528\u7a0b\u5e8f\u53c2\u6570\uff08args\uff09\u548cJVM\u53c2\u6570\uff08jvmArgs\uff09\u3002<\/p>\n<p>\u4f8b\u5b50\uff1a\u8bf7\u4f60\u5e2e\u5fd9\u628a\u8fd9\u672c\u4e66\u62ff\u7ed9\u6211\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">bootRun<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">args<\/span> <span class=\"o\">+=<\/span> <span class=\"o\">[<\/span><span class=\"s1\">'-X'<\/span><span class=\"o\">,<\/span> <span class=\"s1\">'-F'<\/span><span class=\"o\">]<\/span>\r\n    <span class=\"n\">jvmArgs<\/span> <span class=\"o\">+=<\/span> <span class=\"o\">[<\/span><span class=\"s1\">'-Dspring.profiles.active=dev'<\/span><span class=\"o\">]<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/code><\/pre>\n<h4>Redis\u9a71\u52a8\u7a0b\u5e8f\u7684\u66f4\u6539<\/h4>\n<p>\u5728spring-boot-starter-redis\u4e2d\uff0c\u9ed8\u8ba4\u7684Redis\u9a71\u52a8\u7a0b\u5e8f\u7531Jedis\u66f4\u6539\u4e3aLettuce\u3002<\/p>\n<h4>Mockito 1.x:<br \/>\nMockito 1.x\uff1a\u68c0\u9a8c\u6846\u67b6<\/h4>\n<p>\u5728 Mockito 1.x \u7248\u672c\u4e2d\uff0c\u65e0\u6cd5\u4f7f\u7528 @MockBean \u548c @SpyBean \u6765\u8fdb\u884c\u5bf9\u8c61\u6ce8\u5165\u3002<br \/>\n\u5982\u679c\u4e0d\u4f7f\u7528 spring-boot-starter-test \u5e93\uff0c\u5c31\u9700\u8981\u624b\u52a8\u5347\u7ea7\u5230 Mockito 2.x \u7248\u672c\u3002<\/p>\n<h4>\u652f\u6301<\/h4>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">OAuth 2.0<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Java9<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Micrometer 1.0.0-rc.2<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">JSON-B<\/ul>\n<h4>\u2605 Spring Framework 5.0 GA<\/h4>\n<p>\u2605 \u6625\u5b63\u6846\u67b65.0 GA<\/p>\n<p>Spring Framework 5.0\u8fdb\u5165\u6b63\u5f0f\u53d1\u5e03\u9636\u6bb5\u3002<\/p>\n<p>\u4ece\u8fd9\u4e2a\u91cc\u7a0b\u7891\u5f00\u59cb\uff0cSpring Framework 5.0 GA\u7248\u5df2\u7ecf\u5f00\u59cb\u4f7f\u7528\u3002<\/p>\n<h3>Spring-Boot-2.0.0-M6\u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 M6 Configuration Changelog<\/ul>\n<h4>Gradle\u63d2\u4ef6\u7684\u66f4\u6539<\/h4>\n<p>\u5728BootRun\u3001BootJar\u548cBootWar\u4efb\u52a1\u4e2d\uff0c\u73b0\u5728\u53ef\u4ee5\u4f7f\u7528mainClassName\u5c5e\u6027\u8fdb\u884c\u914d\u7f6e\u3002\u5728\u6b64\u4e4b\u524d\uff0c\u9700\u8981\u901a\u8fc7\u5404\u4e2a\u4efb\u52a1\u7684\u5c5e\u6027\u8fdb\u884c\u8bbe\u7f6e\u3002<\/p>\n<h4>JPA\u7684open-in-view\u5c5e\u6027\u7684\u8b66\u544a<\/h4>\n<p>\u9ed8\u8ba4\u503c\u4e3atrue\uff0c\u4f46\u5982\u679c\u4e0d\u660e\u786e\u5c06\u8be5\u5c5e\u6027\u7684\u503c\u8bbe\u7f6e\u4e3atrue\uff0c\u5219\u4f1a\u5728\u542f\u52a8\u65f6\u663e\u793a\u8b66\u544a\u6d88\u606f\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.jpa.open-in-view<\/span><span class=\"p\">=<\/span> <span class=\"s\">true<\/span>\r\n<\/code><\/pre>\n<p>\u8b66\u544a\u4fe1\u606f<\/p>\n<pre class=\"post-pre\"><code>spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning\r\n<\/code><\/pre>\n<h4>\u914d\u7f6e\u4f4d\u7f6e<\/h4>\n<p>\u57282.0\u7248\u672c\u4e2d\uff0c\u8bbe\u7f6eapplication.properties\u7684\u641c\u7d22\u8def\u5f84\u7684\u65b9\u6cd5\u5df2\u7ecf\u6539\u53d8\u3002<\/p>\n<p>1.5\u4e4b\u524d\uff0c\u5c06\u8def\u5f84\u8bbe\u7f6e\u4e3a&#8221;spring.config.location&#8221;\u7684\u8def\u5f84\u4f1a\u88ab\u6dfb\u52a0\u5230\u9ed8\u8ba4\u7684\u641c\u7d22\u8def\u5f84\u4e2d\u3002<br \/>\n\u4ece2.0\u5f00\u59cb\uff0c\u5c06\u8def\u5f84\u8bbe\u7f6e\u4e3a&#8221;spring.config.location&#8221;\u4f1a\u66ff\u6362\u6389\u9ed8\u8ba4\u7684\u641c\u7d22\u8def\u5f84\u3002\u5982\u679c\u60f3\u8981\u6dfb\u52a0\u641c\u7d22\u8def\u5f84\uff0c\u53ef\u4ee5\u4f7f\u7528\u65b0\u7684\u5c5e\u6027&#8221;additional-location&#8221;\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.config.additional-location= # Config file locations used in addition to the defaults.\r\n<\/code><\/pre>\n<h4>ConfigurationProperties\u7684\u9a8c\u8bc1<\/h4>\n<p>\u8981\u5bf9\u4f7f\u7528\u4e86ConfigurationProperties\u6ce8\u89e3\u7684\u5bf9\u8c61\u8fdb\u884c\u9a8c\u8bc1\uff0c\u9700\u8981\u6dfb\u52a0Validated\u6ce8\u89e3\u3002<\/p>\n<p>\u53ef\u4ee5\u53ea\u63d0\u4f9b\u4e00\u79cd\u4e2d\u6587\u7ffb\u8bd1\u7684\u6539\u5199\u5982\u4e0b\uff1a<\/p>\n<p>\u4f8b\u5b50<\/p>\n<p>\u5982\u679c\u8981\u5c06\u4ee5\u4e0b\u5c5e\u6027\u7ed1\u5b9a\u5230FooConfig\u7c7b\u4e2d\uff0c\u53ef\u4ee5\u8fd9\u6837\u505a\uff1a<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">my-app.my-module.foo.first-name<\/span><span class=\"p\">=<\/span> <span class=\"s\">ruby<\/span>\r\n<span class=\"c\">#my-app.my-module.foo.last-name= tomato\r\n#my-app.my-module.foo.age= 77\r\n<\/span><span class=\"py\">my-app.my-module.foo.bar-settings.max-height<\/span><span class=\"p\">=<\/span> <span class=\"s\">999<\/span>\r\n<span class=\"py\">my-app.my-module.foo.bar-settings.min-height<\/span><span class=\"p\">=<\/span> <span class=\"s\">100<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"nd\">@Component<\/span>\r\n<span class=\"nd\">@ConfigurationProperties<\/span><span class=\"p\">(<\/span><span class=\"n\">prefix<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"my-app.my-module.foo\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nd\">@Validated<\/span>\r\n<span class=\"kd\">class<\/span> <span class=\"nc\">FooConfig<\/span> <span class=\"p\">{<\/span>\r\n\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">firstName<\/span><span class=\"p\">:<\/span> <span class=\"nc\">String<\/span>\r\n\r\n    <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">lastName<\/span><span class=\"p\">:<\/span> <span class=\"nc\">String<\/span>\r\n\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">age<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Int<\/span><span class=\"p\">?<\/span> <span class=\"p\">=<\/span> <span class=\"k\">null<\/span>\r\n\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">barSettings<\/span><span class=\"p\">:<\/span> <span class=\"nc\">BarConfig<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">BarConfig<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"kd\">class<\/span> <span class=\"nc\">BarConfig<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">maxHeight<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Integer<\/span>\r\n        <span class=\"k\">lateinit<\/span> <span class=\"kd\">var<\/span> <span class=\"py\">minHeight<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Integer<\/span>\r\n        <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">toString<\/span><span class=\"p\">():<\/span> <span class=\"nc\">String<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"k\">return<\/span> <span class=\"s\">\"BarConfig(maxHeight=$maxHeight, minHeight=$minHeight)\"<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">toString<\/span><span class=\"p\">():<\/span> <span class=\"nc\">String<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"s\">\"FooConfig(firstName='$firstName', lastName='$lastName', age=$age, barSettings=$barSettings)\"<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u53ea\u8981\u6709\u9a8c\u8bc1\u8fc7\u7684\u6ce8\u91ca\uff0c\u5e94\u7528\u7a0b\u5e8f\u5728\u542f\u52a8\u65f6\u5c31\u4f1a\u8fdb\u884c\u9a8c\u8bc1\uff0c\u5982\u679cNotNull\u5c5e\u6027\u65e0\u6cd5\u521d\u59cb\u5316\uff0c\u5219\u4f1a\u8f93\u51fa\u9519\u8bef\u5e76\u7ec8\u6b62\u3002<\/p>\n<pre class=\"post-pre\"><code>***************************\r\nAPPLICATION FAILED TO START\r\n***************************\r\n\r\nDescription:\r\n\r\nFailed to bind properties under 'my-app.my-module.foo.last-name' to java.lang.String:\r\n\r\n    Reason: Unable to get value for property last-name\r\n\r\nAction:\r\n\r\nUpdate your application's configuration\r\n<\/code><\/pre>\n<p>\u5982\u679c\u6ca1\u6709\u6dfb\u52a0Validated\u6ce8\u91ca\uff0c\u5219\u5e94\u7528\u7a0b\u5e8f\u4f1a\u542f\u52a8\uff0c\u4f46\u5728\u9996\u6b21\u8bbf\u95eeFooConfig\u7684\u5c5e\u6027\u65f6\u4f1a\u53d1\u751f\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>kotlin.UninitializedPropertyAccessException: lateinit property lastName has not been initialized\r\n<\/code><\/pre>\n<h5>\u4ea7\u6743\u7684\u8d77\u6e90<\/h5>\n<p>\u5982\u679c\u65e0\u6cd5\u5c06\u5c5e\u6027\u7ed1\u5b9a\uff08\u4f8b\u5982\u629b\u51faBindException\u7b49\u539f\u56e0\uff09\uff0c\u5219\u4f1a\u663e\u793a\u8be5\u5c5e\u6027\u7684\u5c5e\u6027\u6e90\u3002<\/p>\n<p>\u5f53\u6307\u5b9a\u7684\u5c5e\u6027\u201c-Dmy-app.my-module.foo.color=white\u201d\u65e0\u6cd5\u4e0emy-app.my-module.foo.color\u7ed1\u5b9a\u65f6\uff0c\u5c06\u663e\u793a\u4ee5\u4e0b\u4fe1\u606f\u3002\u539f\u56e0\u662f\u6307\u5b9a\u7684\u201cwhite\u201d\u503c\u65e0\u6cd5\u7ed1\u5b9a\u5230\u679a\u4e3e\u7c7b\u578b\u7684Color\u5b57\u6bb5\u3002\u4ece\u6d88\u606f\u4e2d\u7684\u201cOrigin\u201d\u884c\u53ef\u4ee5\u786e\u8ba4\u8be5\u503c\u662f\u7531\u201cSystemProperties\u201d\u6307\u5b9a\u7684\u3002<\/p>\n<pre class=\"post-pre\"><code>***************************\r\nAPPLICATION FAILED TO START\r\n***************************\r\n\r\nDescription:\r\n\r\nFailed to bind properties under 'my-app.my-module.foo.color' to com.example.demomavenspring2.type.Color:\r\n\r\n    Property: my-app.my-module.foo.color\r\n    Value: white\r\n    Origin: \"my-app.my-module.foo.color\" from property source \"systemProperties\"\r\n    Reason: Failed to convert from type [java.lang.String] to type [@javax.validation.constraints.NotNull com.example.demomavenspring2.type.Color] for value 'white'; nested exception is java.lang.IllegalArgumentException: No en\r\num constant com.example.demomavenspring2.type.Color.white\r\n\r\nAction:\r\n\r\nUpdate your application's configuration. The following values are valid:\r\n\r\n    BLUE\r\n    CYAN\r\n    GREEN\r\n    MAGENTA\r\n    RED\r\n    YELLOW\r\n<\/code><\/pre>\n<h4>\u2605\u6570\u636e\u6e90\u521d\u59cb\u5316<\/h4>\n<p>\u6570\u636e\u5e93\u7684\u521d\u59cb\u5316\u63a7\u5236\u5c5e\u6027\u5df2\u88ab\u4fee\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.datasource.initialize<\/span><span class=\"p\">=<\/span> <span class=\"s\">true<\/span>\r\n<\/code><\/pre>\n<p>\u53ea\u6709\u5185\u7f6e\u6570\u636e\u5e93\uff08H2\u3001HSQL\u3001Derby\uff09\u624d\u80fd\u4f7f\u7528\u65b0\u5c5e\u6027\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.datasource.initialization-mode<\/span><span class=\"p\">=<\/span> <span class=\"s\">embedded<\/span>\r\n<\/code><\/pre>\n<p>\u5728DataSourceInitializationMode\u4e2d\uff0c\u53ef\u4ee5\u6307\u5b9a\u7684\u503c\u6709\u4ee5\u4e0b3\u79cd\u3002\u5f53\u6307\u5b9aalways\u65f6\uff0c\u9700\u8981\u6ce8\u610f\u5373\u4f7f\u4e0d\u4f7f\u7528\u5185\u5d4c\u6570\u636e\u5e93\u4e5f\u4f1a\u542f\u7528\u8be5\u529f\u80fd\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">embedded<\/ul>\n<\/li>\n<\/ul>\n<p>Only initialize an embedded datasource.<\/p>\n<p>always<\/p>\n<p>always initialize the datasource.<\/p>\n<p>never<\/p>\n<p>Do not initialize the datasource.<\/p>\n<h4>JPA\u6620\u5c04\u8d44\u6e90<\/h4>\n<p>\u73b0\u5728\u53ef\u4ee5\u6307\u5b9a\u6620\u5c04\u8d44\u6e90\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.jpa.mapping-resources= # Mapping resources (equivalent to \"mapping-file\" entries in persistence.xml).\r\n<\/code><\/pre>\n<h4>HTTP\/2\u7684\u4e2d\u6587\u91ca\u4e49<\/h4>\n<p>\u5728\u8fd9\u4e2a\u91cc\u7a0b\u7891\u4e2d\uff0cTomcat\u548cUndertow\u5df2\u7ecf\u5bf9HTTP\/2\u7684\u542f\u7528\/\u7981\u7528\u8fdb\u884c\u4e86\u5c5e\u6027\u8bbe\u7f6e\u3002 \uff08Jetty\u5728RC1\u4e2d\u63d0\u4f9b\u652f\u6301\uff09<\/p>\n<pre class=\"post-pre\"><code>server.http2.enabled= true\r\n<\/code><\/pre>\n<p>\u8981\u786e\u8ba4HTTP\/2\u662f\u5426\u5df2\u542f\u7528\uff0c\u8bf7\u542f\u7528SSL\u5e76\u901a\u8fc7HTTPS\u8fdb\u884c\u8bbf\u95ee\u3002<\/p>\n<h4>\u4ece\u81ea\u52a8\u914d\u7f6e\u548c\u4f9d\u8d56\u5173\u7cfb\u7ba1\u7406\u4e2d\u6392\u9664<\/h4>\n<p>\u5982\u679c\u5728\u9879\u76ee\u4e2d\u4f7f\u7528\uff0c\u5fc5\u987b\u660e\u786e\u7248\u672c\u3002<\/p>\n<ul class=\"post-ul\">Spring Mobile<\/ul>\n<h4>Kotlin &#8211; Kotlin<\/h4>\n<p>\u5df2\u7ecf\u51c6\u5907\u4e86\u4e00\u4e2a\u540d\u4e3arunApplication\u7684\u5185\u8054\u51fd\u6570\u3002<\/p>\n<p>1.5\u4e4b\u524d (y\u012b d\u00ec 5 zh\u012b<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">fun<\/span> <span class=\"nf\">main<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Array<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nc\">SpringApplication<\/span><span class=\"p\">.<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"nc\">Application<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">,<\/span> <span class=\"p\">*<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u57282.0\u7248\u672c\u53ca\u4ee5\u540e\uff0c\u4e5f\u53ef\u4ee5\u7528\u4ee5\u4e0b\u65b9\u5f0f\u8fdb\u884c\u63cf\u8ff0\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">fun<\/span> <span class=\"nf\">main<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Array<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">runApplication<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Application<\/span><span class=\"p\">&gt;(*<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u6216\u8005<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">fun<\/span> <span class=\"nf\">main<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Array<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">runApplication<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">Application<\/span><span class=\"p\">&gt;(*<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"c1\">\/\/ initialize code<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<h3>Spring Boot 2.0.0\u7684M7\u7248\u672c\u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 M7 Configuration Changelog<\/ul>\n<h4>\u66f4\u6539Jackson\u5e8f\u5217\u5316\u7684\u9ed8\u8ba4\u503c\u3002<\/h4>\n<p>serialization.write-dates-as-timestamps\u5c5e\u6027\u7684\u9ed8\u8ba4\u503c\u5df2\u66f4\u6539\u4e3afalse\u3002<\/p>\n<p>\u793a\u4f8b\u4ee3\u7801 \uff08 \uff09<\/p>\n<p>\u6211\u786e\u8ba4\u4e86\u4e0b\u5217\u6570\u636e\u7c7b\u7684\u5b9e\u4f8b\u5c06\u5982\u4f55\u8fdb\u884c\u5e8f\u5217\u5316\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kd\">data class<\/span> <span class=\"nc\">DateTimeDemo<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">lt<\/span><span class=\"p\">:<\/span> <span class=\"nc\">LocalTime<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">LocalTime<\/span><span class=\"p\">.<\/span><span class=\"nf\">now<\/span><span class=\"p\">(),<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">ld<\/span><span class=\"p\">:<\/span> <span class=\"nc\">LocalDate<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">LocalDate<\/span><span class=\"p\">.<\/span><span class=\"nf\">now<\/span><span class=\"p\">(),<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">dt<\/span><span class=\"p\">:<\/span> <span class=\"nc\">LocalDateTime<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">LocalDateTime<\/span><span class=\"p\">.<\/span><span class=\"nf\">now<\/span><span class=\"p\">(),<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">ym<\/span><span class=\"p\">:<\/span> <span class=\"nc\">YearMonth<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">YearMonth<\/span><span class=\"p\">.<\/span><span class=\"nf\">now<\/span><span class=\"p\">(),<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">md<\/span><span class=\"p\">:<\/span> <span class=\"nc\">MonthDay<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">MonthDay<\/span><span class=\"p\">.<\/span><span class=\"nf\">now<\/span><span class=\"p\">(),<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">dd<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Duration<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">Duration<\/span><span class=\"p\">.<\/span><span class=\"nf\">of<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"nc\">ChronoUnit<\/span><span class=\"p\">.<\/span><span class=\"nc\">HOURS<\/span><span class=\"p\">),<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">pp<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Period<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">Period<\/span><span class=\"p\">.<\/span><span class=\"nf\">ofDays<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">),<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">ii<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Instant<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">Instant<\/span><span class=\"p\">.<\/span><span class=\"nf\">now<\/span><span class=\"p\">()<\/span>\r\n<span class=\"p\">)<\/span> <span class=\"p\">:<\/span> <span class=\"nc\">Serializable<\/span>\r\n<\/code><\/pre>\n<p>\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u662f2.0\u7248\u672c\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.jackson.serialization.write-dates-as-timestamps= false\r\nspring.jackson.serialization.write-durations-as-timestamps= true\r\n<\/code><\/pre>\n<p>\u8bf7\u7528\u4e2d\u6587\u8fdb\u884c\u672c\u5730\u5316\u91cd\u8ff0\uff0c\u53ea\u9700\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\uff1a<br \/>\n\u2193<\/p>\n<p>\u8bf7\u5c06\u4ee5\u4e0b\u5185\u5bb9\u7528\u4e2d\u6587\u91cd\u65b0\u8868\u8fbe\uff0c\u53ea\u9700\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\uff1a<\/p>\n<pre class=\"post-pre\"><code>{\r\n    lt: \"14:06:20.9023938\",\r\n    ld: \"2018-02-16\",\r\n    dt: \"2018-02-16T14:06:20.9023938\",\r\n    ym: \"2018-02\",\r\n    md: \"--02-16\",\r\n    dd: \"PT1H\",\r\n    pp: \"P1D\",\r\n    ii: \"2018-02-16T05:06:20.904893500Z\"\r\n}\r\n<\/code><\/pre>\n<p>\u5f531.5\u88ab\u8bbe\u7f6e\u4e3a\u9ed8\u8ba4\u503c\u65f6\uff08\u4e5f\u9002\u7528\u4e8eJackson\u7684\u9ed8\u8ba4\u503c\uff09<\/p>\n<pre class=\"post-pre\"><code>spring.jackson.serialization.write-dates-as-timestamps= true\r\nspring.jackson.serialization.write-durations-as-timestamps= true\r\n<\/code><\/pre>\n<p>\u8bf7\u7528\u4e2d\u6587\u7ffb\u8bd1\u4ee5\u4e0b\u5185\u5bb9\uff08\u53ea\u9700\u63d0\u4f9b\u4e00\u79cd\u9009\u62e9\uff09\uff1a<br \/>\n\u2193<\/p>\n<pre class=\"post-pre\"><code>{\r\n    lt: [\r\n        14,\r\n        7,\r\n        43,\r\n        61545000\r\n    ],\r\n    ld: [\r\n        2018,\r\n        2,\r\n        16\r\n    ],\r\n    dt: [\r\n        2018,\r\n        2,\r\n        16,\r\n        14,\r\n        7,\r\n        43,\r\n        61545000\r\n    ],\r\n    ym: [\r\n        2018,\r\n        2\r\n    ],\r\n    md: \"--02-16\",\r\n    dd: 3600,\r\n    pp: \"P1D\",\r\n    ii: 1518757663.0645459\r\n}\r\n<\/code><\/pre>\n<h4>Kotlin &#8211; Kotlin is a programming language that can be used natively in Chinese.<\/h4>\n<p>\u5220\u9664\u4e86spring-boot-starter-json\u5bf9jackson-module-kotlin\u7684\u4f20\u9012\u6027\u4f9d\u8d56\u5173\u7cfb\u3002<br \/>\n\u5982\u679c\u5728Kotlin\u4e2d\u4f7f\u7528jackson\uff0c\u5219\u9700\u8981\u624b\u52a8\u6dfb\u52a0\u4f9d\u8d56\u5173\u7cfb\u3002<\/p>\n<p>\u9b54\u955c<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;dependency&gt;<\/span>\r\n    <span class=\"nt\">&lt;groupId&gt;<\/span>com.fasterxml.jackson.module<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n    <span class=\"nt\">&lt;artifactId&gt;<\/span>jackson-module-kotlin<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<\/code><\/pre>\n<p>Gradle<br \/>\n\u8fdb\u9636<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"com.fasterxml.jackson.module:jackson-module-kotlin\"<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<h4>Spring Data\u4ed3\u5e93\u7684\u542f\u7528\u529f\u80fd<\/h4>\n<p>\u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u53cd\u5e94\u6027\u7684\u6570\u636e\u5b58\u50a8\u5e93\uff0c\u5df2\u6539\u53d8\u5b58\u50a8\u5e93\u542f\u7528\/\u7981\u7528\u5c5e\u6027\u3002<\/p>\n<p>\u5728\u4ee5\u5f80\u7684\u5c5e\u6027\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528true\/false\u6765\u8fdb\u884c\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.data.cassandra.repositories.enabled=\r\nspring.data.mongodb.repositories.enabled=\r\nspring.data.redis.repositories.enabled= \r\nspring.data.couchbase.repositories.enabled=\r\n<\/code><\/pre>\n<p>\u5728Redis\u4ee5\u5916\u7684\u90e8\u5206\uff0c\u53ef\u4ee5\u9009\u62e9\u65b0\u7684\u5c5e\u6027\uff0c\u5305\u62ecauto\uff08\u9ed8\u8ba4\uff09\u3001imperative\u3001reactive\u548cnone\u3002<br \/>\nRedis\u4f3c\u4e4e\u6ca1\u6709\u4efb\u4f55\u53d8\u5316\uff0c\u4ecd\u7136\u4fdd\u6301\u4ee5\u524d\u7684\u6837\u5b50\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.data.cassandra.repositories.type<\/span><span class=\"p\">=<\/span> <span class=\"s\">auto<\/span>\r\n<span class=\"py\">spring.data.mongodb.repositories.type<\/span><span class=\"p\">=<\/span> <span class=\"s\">auto<\/span>\r\n<span class=\"py\">spring.data.redis.repositories.enabled<\/span><span class=\"p\">=<\/span> <span class=\"s\">true<\/span>\r\n<span class=\"py\">spring.data.couchbase.repositories.type<\/span><span class=\"p\">=<\/span> <span class=\"s\">auto<\/span>\r\n<\/code><\/pre>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">auto<\/ul>\n<\/li>\n<\/ul>\n<p>enables all repository types automatically based on their availability<\/p>\n<p>imperative<\/p>\n<p>enables imperative repisitories<\/p>\n<p>reactive<\/p>\n<p>enables reactive repositories<\/p>\n<p>none<\/p>\n<p>enables no repositories<\/p>\n<p>\u53ea\u6709Redis\u6ca1\u6709type\u5c5e\u6027\u3002<\/p>\n<p>\u5f53\u68c0\u67e5\u6bcf\u4e2astarter\u7684pom.xml\u6587\u4ef6\u65f6(spring-boot-starter-data-redis\u3001spring-boot-starter-data-redis-reactive)\uff0c\u53ef\u4ee5\u770b\u51fa\uff0creactive\u7248\u672c\u4f3c\u4e4e\u53ea\u662f\u4f20\u7edf\u7248\u672c\u7684\u522b\u540d\uff0c\u6ca1\u6709\u4efb\u4f55\u533a\u522b\u3002<\/p>\n<h4>\u6392\u9664\u81ea\u52a8\u914d\u7f6e\u548c\u4f9d\u8d56\u5173\u7cfb\u7ba1\u7406<\/h4>\n<p>\u5982\u679c\u5728\u9879\u76ee\u4e2d\u4f7f\u7528\uff0c\u5c31\u9700\u8981\u660e\u786e\u7248\u672c\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Spring Social<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">commons-digester<\/ul>\n<h4>\u91cd\u542f\u65f6\u7684\u6761\u4ef6\u8bc4\u4f30\u5dee\u5f02<\/h4>\n<p>\u542f\u7528\u4e86DevTools\u7684\u5e94\u7528\u7a0b\u5e8f\u5728\u542f\u52a8\u671f\u95f4\uff0c\u5f53\u7c7b\u8def\u5f84\u66f4\u65b0\u65f6\u4f1a\u81ea\u52a8\u91cd\u65b0\u542f\u52a8\u3002<br \/>\n\u66f4\u65b0\u7c7b\u8def\u5f84\u7684\u65b9\u6cd5\u56e0IDE\u800c\u5f02\u3002\u5728Eclipse\u4e2d\uff0c\u5f53\u4fdd\u5b58\u66f4\u6539\u7684\u6587\u4ef6\u65f6\uff0c\u5728IntelliJ IDEA\u4e2d\uff0c\u9879\u76ee\u6784\u5efa\uff08Ctrol + F9\uff09\u6216\u6587\u4ef6\u91cd\u65b0\u7f16\u8bd1\uff08Ctrl + Shift + F9\uff09\u4e5f\u4f1a\u4ea7\u751f\u76f8\u540c\u7684\u6548\u679c\u3002<\/p>\n<p>\u8981\u63a7\u5236\u91cd\u65b0\u542f\u52a8\uff0c\u8bf7\u8bbe\u7f6e\u4ee5\u4e0b\u5c5e\u6027\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.devtools.restart.enabled= false\r\n<\/code><\/pre>\n<p>\u5f53\u68c0\u6d4b\u5230\u5728\u91cd\u65b0\u542f\u52a8\u65f6\u5e94\u7528\u7a0b\u5e8f\u7684\u81ea\u52a8\u914d\u7f6e\u53d1\u751f\u66f4\u6539\uff0c\u66f4\u6539\u5185\u5bb9\u5c06\u88ab\u8f93\u51fa\u5230\u540d\u4e3a&#8221;CONDITION EVALUATION DELTA&#8221;\u7684\u62a5\u544a\u4e2d\u3002\uff08\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728\u505c\u6b62\u548c\u542f\u52a8\u65f6\u4e0d\u4f1a\u8f93\u51fa\u62a5\u544a\uff0c\u4ec5\u5728\u81ea\u52a8\u91cd\u542f\u65f6\u624d\u4f1a\u8f93\u51fa\u3002\uff09\u82e5\u8981\u63a7\u5236\u62a5\u544a\u7684\u8f93\u51fa\uff0c\u8bf7\u8bbe\u7f6e\u4ee5\u4e0b\u5c5e\u6027\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.devtools.restart.log-condition-evaluation-delta= false\r\n<\/code><\/pre>\n<h4>application.properties\u6587\u4ef6\u4e2d\u7684Duration\u7c7b\u578b<\/h4>\n<p>\u5982\u679c\u5c5e\u6027\u662fJava Duration\u7c7b\u578b\uff0c\u73b0\u5728\u53ef\u4ee5\u5728\u540e\u7f00\u4e2d\u6dfb\u52a0\u5355\u4f4d\u6765\u6307\u5b9a\uff0c\u4f8b\u5982&#8221;1h&#8221;\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">server.session.cookie.max-age<\/span><span class=\"p\">=<\/span> <span class=\"s\">1h<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u4e0d\u6dfb\u52a0\u540e\u7f00\uff0c\u5219\u5c06\u4fdd\u6301\u4f20\u7edf\u7684\u5355\u4f4d\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># Maximum age of the session cookie. If a duration suffix is not specified, seconds will be used.\r\n<\/span><span class=\"py\">server.session.cookie.max-age<\/span><span class=\"p\">=<\/span> <span class=\"s\">3600<\/span>\r\n<\/code><\/pre>\n<p>\u7136\u800c\uff0c\u7531\u4e8e\u8fd8\u5b58\u5728\u4e00\u4e9b\u4e0d\u63a5\u53d7Duration\u7c7b\u578b\u53c2\u6570\u7684\u5c5e\u6027\u9700\u8981\u6307\u5b9a\u65f6\u95f4\u7684\u957f\u5ea6\uff0c\u6240\u4ee5\u9700\u8981\u6ce8\u610f\u3002<br \/>\n\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u4e0b\u9762\u7684max-age\u662fLong\u7c7b\u578b\uff0c\u5982\u679c\u6dfb\u52a0\u540e\u7f00\u4f1a\u5bfc\u81f4\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.datasource.tomcat.max-age<\/span><span class=\"p\">=<\/span> <span class=\"s\">30s<\/span>\r\n<\/code><\/pre>\n<h4>\u5f53\u4f7f\u7528Redis\u4f5c\u4e3a\u7f13\u5b58\u65f6\u7684\u9ed8\u8ba4\u8bbe\u7f6e\u3002<\/h4>\n<p>\u73b0\u5728\u53ef\u4ee5\u5728application.properties\u4e2d\u8bbe\u7f6e\u4f7f\u7528Redis\u4f5c\u4e3a\u7f13\u5b58\u7684\u9ed8\u8ba4\u503c\u3002<\/p>\n<p>\u9009\u62e9Redis\u4f5c\u4e3a\u7f13\u5b58\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.cache.type<\/span><span class=\"p\">=<\/span> <span class=\"s\">redis<\/span>\r\n<\/code><\/pre>\n<p>\u60a8\u53ef\u4ee5\u5728\u4ee5\u4e0b\u5c5e\u6027\u4e2d\u8bbe\u7f6e\u9ed8\u8ba4\u503c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">spring.cache.redis.time-to-live<\/span><span class=\"p\">=<\/span> <span class=\"s\">120s<\/span>\r\n<span class=\"py\">spring.cache.redis.cache-null-values<\/span><span class=\"p\">=<\/span> <span class=\"s\">true<\/span>\r\n<span class=\"py\">spring.cache.redis.use-key-prefix<\/span><span class=\"p\">=<\/span> <span class=\"s\">true<\/span>\r\n<span class=\"py\">spring.cache.redis.key-prefix<\/span><span class=\"p\">=<\/span> <span class=\"s\">myCache_<\/span>\r\n<\/code><\/pre>\n<p>\u6b64\u5c5e\u6027\u5c06\u53cd\u6620\u5230Class CacheProperties\u4e2d\u3002<\/p>\n<p>\u5f53\u5c06cache-null-values\u5c5e\u6027\u8bbe\u7f6e\u4e3afalse\u65f6\uff0c\u8bd5\u56fe\u7f13\u5b58null\u503c\u4f1a\u629b\u51faIllegalArgumentException\u5f02\u5e38\u3002<br \/>\n\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u8bbe\u7f6e\u5982\u4e0b\u6765\u6392\u9664null\u503c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@Cacheable<\/span><span class=\"p\">(<\/span><span class=\"n\">cacheNames<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"myCache\"<\/span><span class=\"p\">],<\/span> <span class=\"n\">unless<\/span><span class=\"p\">=<\/span><span class=\"s\">\"#result == null\"<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<h4>\u6dfb\u52a0spring-boot-starter-data-couchbase-reactive<\/h4>\n<p>Couchbase\u5df2\u7ecf\u88ab\u6dfb\u52a0\u5230\u652f\u6301Reactive\u5e94\u7528\u7684\u6570\u636e\u4ed3\u5e93\u4e2d\u4e86\u3002\uff08MongoDB\u3001Redis\u3001Cassandra\u5728M1\u4e2d\u5df2\u7ecf\u652f\u6301\uff09<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">spring-boot-starter-data-couchbase<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">spring-boot-starter-data-couchbase-reactive<\/ul>\n<h3>Spring Boot 2.0.0 RC1 \u53d1\u5e03\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Spring Boot 2.0.0 RC1 Configuration Changelog<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">asciidoc<\/ul>\n<h4>\u5220\u9664\u5bf9spring-boot-starter-web\u7684\u4f9d\u8d56<\/h4>\n<p>spring-boot-starter-freemarker\u7684\u4f9d\u8d56\u5df2\u88ab\u79fb\u9664\u5e76\u8f6c\u4e3a\u4f9d\u8d56\u4e8espring-boot-starter-web\u3002\uff08spring-boot-starter-mustache\u548cspring-boot-starter-thymeleaf\u5728M1\u7248\u672c\u4e2d\u5df2\u505a\u76f8\u5e94\u66f4\u65b0\uff09<\/p>\n<h4>Spring MVC\u8def\u5f84\u5339\u914d\u7684\u66f4\u6539 (Simplified Chinese)<\/h4>\n<p>\u540e\u7f00\u8def\u5f84\u5339\u914d\u7684\u9ed8\u8ba4\u884c\u4e3a\u5df2\u7ecf\u6539\u53d8\u3002<br \/>\n\u56e0\u6b64\uff0c\u65b0\u589e\u4e86\u4e00\u4e2a\u65b0\u53c2\u6570\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.mvc.content-negotiation.favor-parameter= false\r\nspring.mvc.content-negotiation.favor-path-extension= false\r\nspring.mvc.content-negotiation.parameter-name= \r\n<\/code><\/pre>\n<p>1.5\u4ee5\u5185\uff0c\u4f8b\u5982\u8fd9\u4e9b\u8bf7\u6c42\u5168\u90e8\u53ef\u4ee5\u3002<\/p>\n<pre class=\"post-pre\"><code>localhost:\/\/app\/product\r\nlocalhost:\/\/app\/product.json\r\nlocalhost:\/\/app\/product.xml\r\n<\/code><\/pre>\n<p>\u5c3d\u7ba1\u4e0b\u8ff0\u5904\u7406\u7a0b\u5e8f\u65b9\u6cd5\u66fe\u6620\u5c04\u8fc7\uff0c\u4f46\u4ece2.0\u7248\u672c\u5f00\u59cb\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u4e0d\u518d\u8fdb\u884c\u6620\u5c04 (\u8fd4\u56de404 Not Found)\u3002<\/p>\n<pre class=\"post-pre\"><code>@GetMapping(path = [\"\/app\/product\"])\r\nfun product(): String {\r\n\r\n    \/\/... \u7701\u7565\r\n\r\n}\r\n<\/code><\/pre>\n<h4>\u66f4\u6539 application.properties \u7684\u547d\u540d\u7a7a\u95f4<\/h4>\n<div>\n<div class=\"post-table\">oldnewbanner.*spring.banner.*spring.metrics.*management.metrics.*server.*server.servlet.*<\/div>\n<\/div>\n<h4>\u2605\u9057\u4ea7\u5c5e\u6027\u8fc1\u79fb<\/h4>\n<p>\u7531\u4e8e\u5c5e\u6027\u6587\u4ef6\u7684\u7ed3\u6784\u53d1\u751f\u4e86\u91cd\u5927\u53d8\u5316\uff0c\u56e0\u6b64\u63d0\u4f9b\u4e86\u4e00\u4e2a\u540d\u4e3aspring-boot-properties-migrator\u7684\u5c5e\u6027\u6587\u4ef6\u8fc1\u79fb\u6a21\u5757\u3002<br \/>\n\u5f53\u96c6\u6210\u8fd9\u4e2a\u6a21\u5757\u65f6\uff0c\u5b83\u4f1a\u5728\u5e94\u7528\u7a0b\u5e8f\u542f\u52a8\u65f6\u663e\u793a\u8b66\u544a\uff0c\u5982\u679c\u5b58\u5728\u65e7\u5c5e\u6027\uff0c\u5e76\u4e14\u5c06\u4e34\u65f6\u5c06\u5176\u8f6c\u6362\u4e3a\u65b0\u7ed3\u6784\u540e\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002<br \/>\n\u9700\u8981\u63d0\u9192\u7684\u662f\uff0c\u5b83\u4e0d\u4f1a\u81ea\u52a8\u8f6c\u6362application.properties\u6587\u4ef6\uff0c\u6240\u4ee5\u4fee\u6b63\u5de5\u4f5c\u9700\u8981\u624b\u52a8\u8fdb\u884c\u3002<\/p>\n<p>\u4e13\u5bb6<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;dependency&gt;<\/span>\r\n  <span class=\"nt\">&lt;groupId&gt;<\/span>org.springframework.boot<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n  <span class=\"nt\">&lt;artifactId&gt;<\/span>spring-boot-properties-migrator<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<\/code><\/pre>\n<p>Gradle (natively in Chinese: \u6784\u5efa\u5de5\u5177).<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">runtime<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.springframework.boot:spring-boot-properties-migrator\"<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<p>\u4f8b\u5982<\/p>\n<p>\u5982\u679c\u5b58\u5728\u4ee5\u4e0b\u7c7b\u4f3c\u7684\u65e7\u683c\u5f0f\u63cf\u8ff0<\/p>\n<pre class=\"post-pre\"><code><span class=\"py\">banner.charset<\/span><span class=\"p\">:<\/span> <span class=\"s\">UTF-8 # Banner file encoding.<\/span>\r\n<\/code><\/pre>\n<p>\u5e94\u7528\u7a0b\u5e8f\u542f\u52a8\u65f6\u4f1a\u663e\u793a\u8b66\u544a\u4fe1\u606f\u3002<\/p>\n<pre class=\"post-pre\"><code>WARN 7460 --- [  restartedMain] o.s.b.c.p.m.PropertiesMigrationListener  : \r\nThe use of configuration keys that have been renamed was found in the environment:\r\n\r\nProperty source 'applicationConfig: [classpath:\/application.properties]':\r\n    Key: banner.charset\r\n        Line: 2\r\n        Replacement: spring.banner.charset\r\n\r\n\r\nEach configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.\r\n<\/code><\/pre>\n<h4>Hibernate\u5c5e\u6027\u7684\u914d\u7f6e<\/h4>\n<p>\u60a8\u53ef\u4ee5\u81ea\u5b9a\u4e49Hibernate\u7684\u5c5e\u6027\u3002<\/p>\n<p>\u7a0b\u5f0f\u7bc4\u4f8b<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@Bean<\/span>\r\n<span class=\"k\">fun<\/span> <span class=\"nf\">customizer<\/span><span class=\"p\">()<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">HibernatePropertiesCustomizer<\/span> <span class=\"p\">{<\/span> <span class=\"n\">props<\/span> <span class=\"p\">-&gt;<\/span>\r\n    <span class=\"n\">props<\/span><span class=\"p\">[<\/span><span class=\"s\">\"hibernate.show_sql\"<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span>\r\n    <span class=\"n\">props<\/span><span class=\"p\">[<\/span><span class=\"s\">\"hibernate.format_sql\"<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span>\r\n    <span class=\"n\">props<\/span><span class=\"p\">[<\/span><span class=\"s\">\"hibernate.use_sql_comments\"<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span>\r\n    <span class=\"n\">props<\/span><span class=\"p\">[<\/span><span class=\"s\">\"hibernate.generate_statistics\"<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"k\">true<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u5728application.properties\u6587\u4ef6\u4e2d\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u5c5e\u6027\u8fdb\u884c\u81ea\u5b9a\u4e49\u914d\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.jpa.properties.hibernate.*\r\n<\/code><\/pre>\n<ul class=\"post-ul\">User Guild \/ configurations<\/ul>\n<h4>Redis\u7684\u914d\u7f6e<\/h4>\n<p>\u53ef\u4ee5\u901a\u8fc7RedisCacheConfiguration\u6765\u914d\u7f6eRedisCacheManager\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@Bean<\/span>\r\n<span class=\"k\">fun<\/span> <span class=\"nf\">redisCacheConfig<\/span><span class=\"p\">()<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">RedisCacheConfiguration<\/span><span class=\"p\">.<\/span><span class=\"nf\">defaultCacheConfig<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"p\">.<\/span><span class=\"nf\">entryTtl<\/span><span class=\"p\">(<\/span><span class=\"nc\">Duration<\/span><span class=\"p\">.<\/span><span class=\"nf\">ofMinutes<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"p\">.<\/span><span class=\"nf\">disableCachingNullValues<\/span><span class=\"p\">()<\/span>\r\n<\/code><\/pre>\n<p>\u5728application.properties\u6587\u4ef6\u4e2d\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u5c5e\u6027\u8fdb\u884c\u5b9a\u5236\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.cache.redis.*\r\n<\/code><\/pre>\n<h4>\u652f\u6301<\/h4>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">GSon<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">HTTP\/2 (Jetty)<\/ul>\n<h3>Spring Boot 2.0.0 RC2 \u53d1\u884c\u8bf4\u660e<\/h3>\n<ul class=\"post-ul\">Spring Boot 2.0.0 RC2 Configuration Changelog<\/ul>\n<h4>\u66f4\u6539application.properties<\/h4>\n<p>\u4ee5\u4e0b\u7684\u5c5e\u6027\u5df2\u7ecf\u91cd\u65b0\u914d\u7f6e\u3002\uff08\u4f3c\u4e4e\u5728RC2\u4e2d\u8fdb\u884c\u4e86\u4fee\u8ba2\uff09<\/p>\n<p>\u7aef\u70b9\u7f51\u7edc\u914d\u7f6e<\/p>\n<pre class=\"post-pre\"><code>management.endpoints.web.expose\r\n<\/code><\/pre>\n<p>\u8bf7\u5c06\u4ee5\u4e0b\u5185\u5bb9\u7528\u4e2d\u6587\u8fdb\u884c\u91cd\u8ff0\uff0c\u4ec5\u63d0\u4f9b\u4e00\u79cd\u9009\u62e9\uff1a<br \/>\n\u2193<\/p>\n<p>\u8bf7\u7528\u4e2d\u6587\u8fdb\u884c\u91cd\u65b0\u8868\u8fbe\uff0c\u53ea\u9700\u8981\u4e00\u79cd\u9009\u9879\uff1a<\/p>\n<pre class=\"post-pre\"><code>management.endpoints.web.exposure.include\r\nmanagement.endpoints.web.exposure.exclude\r\n<\/code><\/pre>\n<p>JMX \u914d\u7f6e\u7684\u7aef\u70b9<\/p>\n<pre class=\"post-pre\"><code>management.endpoints.jmx.expose\r\n<\/code><\/pre>\n<p>\u8bf7\u7528\u6c49\u8bed\u5c06\u4ee5\u4e0b\u5185\u5bb9\u8fdb\u884c\u91ca\u4e49\uff0c\u53ea\u9700\u8981\u63d0\u4f9b\u4e00\u79cd\u7248\u672c\uff1a<br \/>\n\u2193<\/p>\n<pre class=\"post-pre\"><code>management.endpoints.jmx.exposure.include\r\nmanagement.endpoints.jmx.exposure.exclude\r\n<\/code><\/pre>\n<h4>Webjars Locator\u7684\u4f9d\u8d56\u7ba1\u7406\u53d8\u66f4<\/h4>\n<p>webjars-locator\u7684\u4f9d\u8d56\u7ba1\u7406\u5df2\u88ab\u66f4\u6539\u4e3awebjars-locator-core\u3002<\/p>\n<p>\u4ece2.0\u5f00\u59cb<\/p>\n<p>Maven \u9a6c\u6587<\/p>\n<pre class=\"post-pre\"><code><span class=\"nt\">&lt;dependency&gt;<\/span>\r\n    <span class=\"nt\">&lt;groupId&gt;<\/span>org.webjars<span class=\"nt\">&lt;\/groupId&gt;<\/span>\r\n    <span class=\"nt\">&lt;artifactId&gt;<\/span>webjars-locator-core<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\r\n    <span class=\"nt\">&lt;version&gt;<\/span>0.35<span class=\"nt\">&lt;\/version&gt;<\/span>\r\n<span class=\"nt\">&lt;\/dependency&gt;<\/span>\r\n<\/code><\/pre>\n<p>Gradle &#8211; \u7075\u6d3b\u5f3a\u5927\u7684\u6784\u5efa\u5de5\u5177<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">compile<\/span><span class=\"o\">(<\/span><span class=\"s2\">\"org.webjars:webjars-locator-core:0.35\"<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<h4>Kotlin &#8211; Kotlin\u8bed\u8a00<\/h4>\n<p>\u5728Spring Boot\u53c2\u8003\u6587\u6863\u7684\u7b2c47\u8282\u4e2d\uff0c\u6dfb\u52a0\u4e86\u5bf9Kotlin\u7684\u652f\u6301\u3002<\/p>\n<ul class=\"post-ul\">Part IV. Spring Boot features | 47. Kotlin support<\/ul>\n<p>\u53e6\u5916\uff0c\u5728Spring Framework\u7684\u53c2\u8003\u8d44\u6599\u4e2d\u4e5f\u6709\u5173\u4e8eKotlin\u7684\u90e8\u5206\u3002<\/p>\n<ul class=\"post-ul\">Spring Framework | Language Support<\/ul>\n<h4>\u81ea\u5b9a\u4e49\u7ed1\u5b9a\u5206\u9694\u7b26<\/h4>\n<p>\u8fc7\u53bb\uff0c\u5982\u679c\u5c5e\u6027\u7684\u7c7b\u578b\u662f\u96c6\u5408\uff0c\u5e76\u4e14\u7ed1\u5b9a\u7684\u503c\uff08\u4f8b\u5982\u5728application.properties\u4e2d\u5b9a\u4e49\uff09\u662f\u7528\u9017\u53f7\u5206\u9694\u7684\uff0c\u5219\u4f1a\u81ea\u52a8\u5c06\u5176\u7ed1\u5b9a\u5230\u96c6\u5408\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code>my-app.my-module.foo.hobbies= shopping,trekking,movies\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"nd\">@Component<\/span>\r\n<span class=\"nd\">@ConfigurationProperties<\/span><span class=\"p\">(<\/span><span class=\"n\">prefix<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"my-app.my-module.foo\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"kd\">data class<\/span> <span class=\"nc\">FooConfig<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"py\">hobbies<\/span><span class=\"p\">:<\/span> <span class=\"nc\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">=<\/span> <span class=\"nf\">mutableListOf<\/span><span class=\"p\">()<\/span>\r\n<span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u4ece2.0\u7248\u672c\u5f00\u59cb\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528\u5206\u9694\u7b26\u6ce8\u91ca\u6765\u6307\u5b9a\u5206\u9694\u7b26\u3002<\/p>\n<pre class=\"post-pre\"><code>my-app.my-module.foo.hobbies= shopping; trekking; movies\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"err\">@<\/span><span class=\"n\">field<\/span><span class=\"p\">:<\/span><span class=\"nc\">Delimiter<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\";\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"kd\">var<\/span> <span class=\"py\">hobbies<\/span><span class=\"p\">:<\/span> <span class=\"nc\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"nc\">String<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">=<\/span> <span class=\"nf\">mutableListOf<\/span><span class=\"p\">()<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u4e0d\u60f3\u4f7f\u7528\u9017\u53f7\u5206\u9694\u5212\u5206\uff0c\u53ef\u4ee5\u6309\u7167\u4ee5\u4e0b\u65b9\u5f0f\u6307\u5b9a\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"err\">@<\/span><span class=\"n\">field<\/span><span class=\"p\">:<\/span><span class=\"nc\">Delimiter<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span> <span class=\"p\">=<\/span> <span class=\"nc\">Delimiter<\/span><span class=\"p\">.<\/span><span class=\"nc\">NONE<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<h4>\u652f\u6301<\/h4>\n<p>Micrometer 1.0-GA<\/p>\n<p>M5\u3067\u306f1.0.0-RC2\u3067\u3057\u305f\u304c\u3001GA\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002<\/p>\n<h4>\u68c0\u6d4bJOOQ\u7684SQLDialect\u3002<\/h4>\n<p>\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u81ea\u52a8\u68c0\u6d4b\u662f\u542f\u7528\u7684\uff0c\u901a\u5e38\u65e0\u9700\u5728application.properties\u4e2d\u660e\u786e\u8bf4\u660e\u3002<\/p>\n<pre class=\"post-pre\"><code>spring.jooq.sql-dialect= # SQL dialect to use. Auto-detected by default.\r\n<\/code><\/pre>\n<ul class=\"post-ul\">org.jooq.SQLDialect<\/ul>\n<h1>\u9644\u52a0\u8bf4\u660e\u7684\u53d1\u5e03\u8bf4\u660e\u3002<\/h1>\n<p>Spring Boot 2.0\u8fc1\u79fb\u6307\u5357\u57fa\u672c\u4e0a\u603b\u7ed3\u4e86\u4eceM1\u5230RC2\u7684\u5185\u5bb9\uff0c\u4f46\u7531\u4e8e\u8fc1\u79fb\u6307\u5357\u4e2d\u53ea\u8bb0\u5f55\u4e86\u4e00\u4e9b\u4e8b\u9879\uff0c\u56e0\u6b64\u6211\u5c06\u8865\u5145\u8bf4\u660e\u3002<\/p>\n<h2>\u66f4\u6539spring.jpa.hibernate.ddl-auto\u7684\u9ed8\u8ba4\u884c\u4e3a\u3002<\/h2>\n<p>\u5728\u4f7f\u7528\u5185\u7f6e\u6570\u636e\u5e93\u65f6\uff0c\u9ed8\u8ba4\u503c\u4e3acreate-drop\uff0c\u5176\u4ed6\u60c5\u51b5\u4e0b\u4e3anone\uff0c\u76f4\u52301.5\u7248\u672c\u3002<\/p>\n<p>2.0\u7248\u672c\u53ca\u4ee5\u540e\u7684\u9ed8\u8ba4\u8bbe\u7f6e\u662f\uff0c\u5728\u4f7f\u7528\u5185\u5d4c\u6570\u636e\u5e93\u4e14\u672a\u4f7f\u7528flyway\/Liquibase\u65f6\uff0c\u91c7\u7528create-drop\u7b56\u7565\uff1b\u5426\u5219\u4f7f\u7528none\u7b56\u7565\u3002<\/p>\n<p>\u8fd9\u4e2a\u5c5e\u6027\u4f3c\u4e4e\u4e0d\u80fd\u66f4\u6539\u5176\u53ef\u8bbe\u7f6e\u7684\u503c\u7684\u5185\u5bb9\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">create-drop<\/ul>\n<\/li>\n<\/ul>\n<p>Create and then destroy the schema at the end of session<\/p>\n<p>create<\/p>\n<p>Create the schema and destroy previous data<\/p>\n<p>none<\/p>\n<p>Disable DDL handling<\/p>\n<p>update<\/p>\n<p>Update the schema if necessary<\/p>\n<p>validate<\/p>\n<p>Validate the schema, make no changes to the database<\/p>\n<h1>Spring Data\u7248\u672c\u5347\u7ea7\u7684\u5f71\u54cd<\/h1>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Spring Data JPA &#8211; Reference Documentation &#8211; Version 1.11.10.RELEASE<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">Spring Data JPA &#8211; Reference Documentation &#8211; Version 2.0.4.RELEASE<\/ul>\n<p>Spring Data Commons\u548cJpa\u4e5f\u8fdb\u884c\u4e86\u7248\u672c\u5347\u7ea7\u3002<br \/>\n\u7531\u4e8e\u8fd9\u4e2a\u7248\u672c\u5347\u7ea7\uff0c\u53ef\u80fd\u9700\u8981\u4fee\u6539\u5b9e\u73b0\u4ee3\u7801\uff0c\u56e0\u4e3a\u63a5\u53e3\u53d1\u751f\u4e86\u6539\u53d8\u3002<\/p>\n<p>\u5173\u4e8eCrudRepository\u63a5\u53e3\uff0c\u6709\u4ee5\u4e0b\u7684\u533a\u522b\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@NoRepositoryBean<\/span>\r\n<span class=\"kd\">public<\/span> <span class=\"kd\">interface<\/span> <span class=\"nc\">CrudRepository<\/span><span class=\"o\">&lt;<\/span><span class=\"no\">T<\/span><span class=\"o\">,<\/span> <span class=\"no\">ID<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Serializable<\/span><span class=\"o\">&gt;<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Repository<\/span><span class=\"o\">&lt;<\/span><span class=\"no\">T<\/span><span class=\"o\">,<\/span> <span class=\"no\">ID<\/span><span class=\"o\">&gt;<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"nd\">@NoRepositoryBean<\/span>\r\n<span class=\"kd\">public<\/span> <span class=\"kd\">interface<\/span> <span class=\"nc\">CrudRepository<\/span><span class=\"o\">&lt;<\/span><span class=\"no\">T<\/span><span class=\"o\">,<\/span> <span class=\"no\">ID<\/span><span class=\"o\">&gt;<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Repository<\/span><span class=\"o\">&lt;<\/span><span class=\"no\">T<\/span><span class=\"o\">,<\/span> <span class=\"no\">ID<\/span><span class=\"o\">&gt;<\/span>\r\n<\/code><\/pre>\n<div>\n<div class=\"post-table\">signatureJPA 1.11.10JPA 2.0.4\u540c\u3058&lt;S extends T&gt; S save(S entity)&lt;S extends T&gt; S save(S entity)\u9055\u3046&lt;S extends T&gt; Iterable&lt;S&gt; save(Iterable&lt;S&gt; entities)&lt;S extends T&gt; Iterable&lt;S&gt; saveAll(Iterable&lt;S&gt; entities)\u9055\u3046T findOne(ID id)Optional&lt;T&gt; findById(ID id)\u9055\u3046boolean exists(ID id)boolean existsById(ID id)\u540c\u3058Iterable&lt;T&gt; findAll()Iterable&lt;T&gt; findAll()\u9055\u3046Iterable&lt;T&gt; findAll(Iterable&lt;ID&gt; ids)Iterable&lt;T&gt; findAllById(Iterable&lt;ID&gt; ids)\u540c\u3058long count()long count()\u9055\u3046void delete(ID id)void deleteById(ID id)\u540c\u3058void delete(T entity)void delete(T entity)\u9055\u3046void delete(Iterable&lt;? extends T&gt; entities)void deleteAll(Iterable&lt;? extends T&gt; entities)\u540c\u3058void deleteAll()void deleteAll()<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u603b\u7ed3 \u9019\u7bc7\u6587\u7ae0\u662f\u95dc\u65bc\u4f7f\u7528Kotlin with Spring Boot 1.5\u4f86\u5be6\u73fe\u7c21\u55ae\u7684Rest API\u7684\uff0c [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-39952","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528kotlin\u548cspring-boot-2-0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684rest-api\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API\" \/>\n<meta property=\"og:description\" content=\"\u603b\u7ed3 \u9019\u7bc7\u6587\u7ae0\u662f\u95dc\u65bc\u4f7f\u7528Kotlin with Spring Boot 1.5\u4f86\u5be6\u73fe\u7c21\u55ae\u7684Rest API\u7684\uff0c [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528kotlin\u548cspring-boot-2-0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684rest-api\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2022-11-22T04:03:37+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-28T18:02:53+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png\" \/>\n<meta name=\"author\" content=\"\u9038, \u79d1\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u9038, \u79d1\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/\",\"name\":\"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2022-11-22T04:03:37+00:00\",\"dateModified\":\"2024-04-28T18:02:53+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487\",\"name\":\"\u9038, \u79d1\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g\",\"caption\":\"\u9038, \u79d1\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keyi\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528kotlin\u548cspring-boot-2-0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684rest-api\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API","og_description":"\u603b\u7ed3 \u9019\u7bc7\u6587\u7ae0\u662f\u95dc\u65bc\u4f7f\u7528Kotlin with Spring Boot 1.5\u4f86\u5be6\u73fe\u7c21\u55ae\u7684Rest API\u7684\uff0c [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u4f7f\u7528kotlin\u548cspring-boot-2-0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684rest-api\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2022-11-22T04:03:37+00:00","article_modified_time":"2024-04-28T18:02:53+00:00","og_image":[{"url":"https:\/\/cdn.qiita.com\/emoji\/twemoji\/unicode\/2b06-fe0f.png"}],"author":"\u9038, \u79d1","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u9038, \u79d1","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"23 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/","name":"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2022-11-22T04:03:37+00:00","dateModified":"2024-04-28T18:02:53+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u4f7f\u7528Kotlin\u548cSpring Boot 2.0\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684Rest API"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487","name":"\u9038, \u79d1","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g","caption":"\u9038, \u79d1"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keyi\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e4%bd%bf%e7%94%a8kotlin%e5%92%8cspring-boot-2-0%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84rest-api%e3%80%82\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/39952","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=39952"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/39952\/revisions"}],"predecessor-version":[{"id":73616,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/39952\/revisions\/73616"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=39952"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=39952"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=39952"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}