#author("2020-07-11T07:03:07+00:00","default:wikiadmin","wikiadmin") #author("2021-11-10T12:31:19+00:00","default:wikiadmin","wikiadmin") -SpringBoot #contents *Application Event非同期 [#lb92fd97] https://medium.com/@bau1537/springframework%E3%81%AB%E3%82%88%E3%82%8B%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E5%AE%9F%E8%A3%85-5accbcc97957 *Componentの生成順序 [#lb9ba860] -@Orderで数値が小さいほど後で生成される。 @Order(10000) @Order(1000) *同じフォームで処理メソッドを変更させる [#c8e0deb0] -HTMLのsubmitとname=hogeとつける -Action側でparams=hoge *静的ファイルの置き場所と優先順位 [#a9874903] 上位2つは他のファイルも混じるのでstaticかpublic推奨 +resources/META-INF/resources/ +resources/ +resources/static/ +resources/public/ *Cache制御 [#r5727de5] **マスターなどのデータキャッシュ [#n3b04247] @CacheableをServiceの戻り値につけるとキャッシュ可能。Service内部での呼出の場合はCacheされないので注意。 **Spring Bootでのthymeleadのキャッシュ無効化 [#zc591260] -spring.thymeleaf.cache = falseに加え -intelljの設定が必要。registoryの変更でcompiler.automake.allow.when.app.runningを有効にしてIntellij再起動 -上記でもうまく行かない(linux intellij) https://qiita.com/takehilo/items/72d2872cc9a89ef9a02a *kotlin対応 [#y352eeb2] -https://www.slideshare.net/CASREAL_seminar/intellij-ideakotlinspring-5 -https://qiita.com/Kaoru_Yamamoto/items/d43a10a7cbdd7e5d7b6b *Tips [#q3628f3c] |項目|内容|備考| |ContextPath変更|server.contextPath=/hoge|staticも大丈夫っぽい| |スキャン対象パッケージ指定|@SpringBootApplication(scanBasePackages = {"com.rutake.xxx"})| *multi module [#v903b715] https://github.com/spring-guides/gs-multi-module/tree/master/complete *20170922 チェック [#udd50bd4] **例外ハンドラー [#id3631df] -ResponseEntityExceptionHandler **認証関連 [#yeb8fa43] -HttpStatusReturningLogoutSuccessHandler -SimpleUrlAuthenticationSuccessHandler -ApplicationEventPublisher -AuthorizationServerConfigurerAdapter *チェック [#m5d37cb2] -RequestBody -@ComponentScan("com.rutake.app") -MapperScan -ConfigurationProperties -@Transactional -springfox-swagger2 -@ConditionalOnBean(HogeProperties.class) -@ConditionalOnProperty("hoge.fuga") -Stream.of(args).anyMatch(StringUtils::isBlank); -@PreAuthorize("permitAll()") -com.jaredsburrows:gradle-license-plugin -@ExceptionHandler & @ResponseStatus(HttpStatus.BAD_REQUEST) -Pageable Page<Emp> page = repository.findAll(new PageRequest(3, 3)); -JsonSerialize.Inclusion.NON_NULL return new Jackson2ObjectMapperBuilder() .serializationInclusion(JsonInclude.Include.NON_NULL) mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); *DIの基本 [#g2737f53] Singletonとなるが、Request単位に作成してほしいなどがあるはず。スコープは4種類? http://jappy.hatenablog.com/entry/2016/06/04/042200 **リクエスト単位にしてほしいBeanの設定 [#f40ac940] @Bean @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) **properitiesのConfigへの読み込み [#gf420c4e] @Bean @ConfigurationProperties(prefix = "myprop.hoge") public HogeProperties hogeProperties() { return new HogeProperties(); } -application.yml myprop: hoge: prop1: prop1 *環境の切り替え [#n7c9d394] java -jar spring-boot-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=production **ymlに環境変数かつデフォルト値 [#z656586c] # myapps com: rutake: yml: value: ${env.test:hogehoge} -ENV_TESTまたはCOM_RUTAKE_YML_VALUEが定義されていればその値 -なければhogehoge **環境変数でのマッピングにデフォルト値 [#oca057e8] @Value("${com.rutake.env.value:test}") private String testFromEnv; COM_RUTAKE_ENV_VALUEの定義がない場合はtestになる。 **環境変数でのマッピング [#yece6af8] @Value("${com.rutake.env.value}") String value; export COM_RUTAKE_ENV_VALUE=value ymlに定義することもできるが、この場合で環境変数のCOM_RUTAKE_ENV_VALUEとOTHER_ENVが定義されていた場合は一致する環境変数である前者が優先される。 com: rutake: env: value: {other.env} *プロジェクト新規作成 [#w0bfdaa9] Spring Bootの雛形をWeb上で作成可能 http://start.spring.io/ *Document [#ya857879] http://terasolunaorg.github.io/guideline/5.3.0.RELEASE/ja/ArchitectureInDetail/WebApplicationDetail/Validation.html *特徴 [#a58f1bbe] -SpringMVCを設定レスにした感じ。 *起動 [#hc69eb91] mvn spring-boot:run ./gradlew bootRun *注意点 [#p9003978] 以下の設定だとDBデータを全部消すので、間違っても利用中のDBに向けてはいけない。 spring.jpa.hibernate.ddl-auto=create updateにしておくと消すことはない。 none何もしない。updateはentityの差分を反映。createは作成するが、消すことはない。create-dropは起動時に作成して、終了時にdropする。 *Cache [#g446f84f] **Cacheableのimportを間違えて(3つある)有効にならずハマった!! [#e51eca35] -buid.gradle compile('org.springframework.boot:spring-boot-starter-cache') -Application.java @EnableCaching -import org.springframework.cache.annotation.Cacheable; SpringFoxのCacheableをimportしてハマる! *トラブル [#ib317326] MACで設定翌日にWebアプリケーションが一切起動しない(どのプロジェクトも)トラブルで死亡。原因不明。ワークスペースを変更してもダメ。 **propertiesファイル [#m465e21d] application.propertiesに設定が必要だった。あとリソースファイルもクラスパスにないとだめ。全自動でできるのかは要調査! **検索対象のパッケージ [#p8837014] デフォルトやデモだと同じパッケージを検索する。 サービスには@ComponentScan("パッケージ名") -componentの探し方 http://yyama1556.hateblo.jp/entry/2016/08/10/175948 *設定 [#jdf4899f] **application.propertiesとapplication.yml [#n684580b] +src/main/resources/config/application.ymlがあるとそれを優先。 +src/main/resources/application.propertiesが次に利用されるが、同じ項目がある場合は無視される。 ***application.yml [#p0cd9892] 設定ファイルではスネークケースもキャメルケースもチェーンケース(driver-class-name)もOK server: port: 9020 spring: datasource: url: jdbc:mysql://mysql.example.com/test username: User password: Password driverClassName: com.mysql.jdbc.Driver jpa: hibernate: ddl-auto: update hoge: fuga: @Value("${hoge.fuga:#{null}") String hoge; @Value("${hoge.fuga.interval:3600}") private long interval; -http://takayukii.me/post/201704041080 *Spring Boot Batch [#i3b1d995] デフォルトでは@SpringBootApplicationが存在するパッケージ以下を検索する。それ以外のパッケージにRepositoryがある場合は@EnableJpaRepositories and its type-safe basePackageClasses=MyRepository.class parameter.を利用する。 *Spring DATA [#w47d037c] http://qiita.com/tag1216/items/55742fdb442e5617f727 **トラブルを防ぐために [#webf32a2] -RequestParamを設定している場合はパスが一致しているだけではなく、パラメータも与える必要がある。合わないと404になる! -アソシエーションにいきなりチャレンジするのではなく単体で成功させるべし -メソッド追加時はパラメータの数が一致していないとわけのわからないエラーとなる。これまた一気に複数あると大変なので成功するシンプルなものから増やしていく -アソシエーションはきちんとキャメルケースになっていないとこれまたわけのわからないエラーとなる(一括置換ではまった) -アソシエーションがあるとデータを全部持ってこようとするので、無効にしたいができるのか? *ログ出力 [#b2f787a2] **Spring JPA SQLログ出力 [#j0f784c2] # for logging logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE **Spring mybatis SQLログ出力 [#l2af1a3c] -mapperのあるパッケージを指定すればOK logging.level.yourpackage=DEBUG **Hikari DBCP [#f9ef587b] logging: config: classpath:logback-spring.xml level: com.zaxxer.hikari: DEBUG *Connection 関連設定 [#ga49d3e8] **検証クエリーの有効化 [#c92c7df0] -Spring Boot 2.0系のデフォルトなら以下のプロパティを入れておくと検証クエリーが有効になる。 hikari: connection-test-query: SELECT 1 FROM DUAL **フェイルオーバー [#xbfe66b0] |failover| |loadbalance| |sequential| *ページング [#va59f470] **Controller [#l65cbe19] -Controllerの各メソッドの引数に以下の値を設定しておくとクエリパラメーターをpageableオブジェクトにまとめてくれる。 @PageableDefault( page = 0, size = 10, sort = {"id"}, direction = Sort.Direction.DESC ) Pageable pageable **Spring JPA [#mfcd982a] -デフォルトで用意されているメソッドの引数にpageableを入れる! Page<T> list = xxxRepository.findAll(pageable); *Thymeleaf [#ta74fc65] **Tips [#j436a197] |テキストとして解釈 | をつけると/は割り算ではなくそのまま出力される|th:text="| ${item.storeName}/${item.normalizedStoreName}"| |エスケープしない|th:utext| |クエリーをつける(固定値でも可能)|th:href="@{/charges/{id}(id=${item.id})}"| **Enum出力 [#lae7bea9] <select> <option th:each="state : ${T(com.rutake.enums.Direction).values()}" th:value="${state.value}" th:text="${state.label}"> </option> </select> spring: profiles: active: local *2.0対応 [#reeebdec] **一時ファイル保存場所 [#eaae8847] |1.5|spring.http.multipart.location=/upload/temp| |2.0以降|spring.servlet.multipart.location=/upload/temp| **JPA [#sf4501be] メソッド名変更 -findOneがgetOne -deleteがdeleteById -updateがupdateAll フィールド名にemptyが使えない -@Columnアノテーションで逃げた SpringSecurityが常に403なので無効化 JPAのgetOneが引けない・・・ ここでギブアップ!! #counter