Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
作って学ぶSpring BootのAuto Configuration / JJUG Nigh...
Search
Ryo Shindo
October 19, 2026
Programming
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
Ryo Shindo
October 19, 2026
More Decks by Ryo Shindo
See All by Ryo Shindo
今こそ知りたいSpring Test / Spring Fest 2020
rshindo
13
7.4k
こわくないソースコードリーディング生活 / JJUG CCC 2019 Fall
rshindo
15
10k
開発者のためのSpring Boot Actuator入門 / jsug-2019-08
rshindo
5
6.6k
早わかりSpring Data JDBC / jsug-2019-01
rshindo
5
4.4k
ふつうのJavaアプリ開発のための自動テスト戦略 / JJUG CCC 2018 Fall
rshindo
9
5.4k
Spring WebFluxで学ぶReactive Application / Introduction to Reactive
rshindo
1
2.5k
まだまだ間に合う!JUnit 5入門 / JJUG CCC 2018 Spring
rshindo
6
3.5k
Spring Data JDBCを使い倒す! / Intruduction to Spring Data JDBC
rshindo
4
2.5k
Other Decks in Programming
See All in Programming
[DroidKnights 2026] Workflow AX: From Auto-Documented Policies to E2E Testing
raeminkang
0
530
AIが実装を担う時代の「技術設計」と「チームマネジメント」
kamina_zzz
2
200
SODA - FACT BOOK(JP)
sodainc
1
40k
Vue.jsで作る空間解析アプリとCapacitorプラグインのData Bridge
hal_spidernight
1
160
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
210
Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜
umigishiaoi
0
150
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
190
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
2
290
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
4
3.3k
Event is what happens
moro
2
3.6k
Spec-driven Development with AI
simas
PRO
0
2.3k
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
3
1.4k
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
Claude Code のすすめ
schroneko
67
230k
My Coaching Mixtape
mlcsv
0
380
Between Models and Reality
mayunak
4
560
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
520
How to build a perfect <img>
jonoalderson
1
6.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
Intergalactic Javascript Robots from Outer Space
tanoku
273
28k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
880
Transcript
作って学ぶ Spring BootのAuto Configuration JJUGナイトセミナー / 2026-10-19 進藤 遼(@shindo_ryo)
自己紹介 進藤 遼 株式会社クレディセゾン 内製開発組織でアーキやったり開発やったり雑用やったり Twitter (現X):
@shindo_ryo Bluesky: @rshindo.bsky.social
勝手に宣伝 多田真敏さんの『作って学ぶ Spring Boot入門』 好評発売中 (多田さん)「買うてください!」
本セッションの目的 "黒魔術"と呼ばれがちなSpring BootのAuto Configurationの 仕組みを理解する Spring Boot初学者やなんとなく使っている人向けです
Bean登録がよく分からない人 Starterを追加するだけで機能が使える理由が分からない人 Auto Configurationという言葉は知っているけれど、仕組みはよく 分からない人
Dependency Injection (DI)とは 日本語にすると「依存性の注入」 単純に言うと依存オブジェクトをクラス内でnewせず クラスの外から受け取る仕組みのこと SpringのDI対象となるオブジェクトのことを
"Spring Bean"と呼ぶ @Service public class NotificationService { DIコンテナ (ApplicationContext) private final JdbcClient jdbcClient; public NotificationService(JdbcClient jdbcClient) { this.jdbcClient = jdbcClient; } } JdbcClientオブジェクトを インジェクション
登場人物 新入社員 地井さん 新入社員 羽地さん
「現在日時を取得するコンポーネントを実装せよ」という 指示を受けた新入社員の地井さんと羽地さん。 @Componentってアノテーションを使うと SpringのBeanができるらしいよッ! 羽地さん ワァッ 地井さん
@ComponentによるBean登録 コンポーネントスキャン対象であれば、クラスに@Componentを つけるだけで自動的にDIコンテナにBean登録される @Component public class SystemDateTimeProvider { public
LocalDateTime now() { return LocalDateTime.now(); } } @Service, @Repositoryなどの アノテーションでもBean登録できる @Service public class NotificationService { private final SystemDateTimeProvider systemDateTimeProvider; public NotificationService(SystemDateTimeProvider systemDateTimeProvider) { this.systemDateTimeProvider = systemDateTimeProvider; } }
コンポーネントスキャン Spring Bootではデフォルトでは@SpringBootApplication以下の階層の パッケージにある@Componentなどがつけられたクラスを 自動的にスキャンしてBean登録する package com.foo; @Service public
class FooService { } package com.foo; @SpringBootApplication public class FooApplication { static void main(String[] args) { SpringApplication.run( FooApplication.class, args); } } スキャンOK package com.foo.bar; @Service public class BarService { } スキャンしない package com.baz; @Service public class BazService { }
登場人物 上司 百々さん
プロパティで固定時間とシステム時間を 切り替えられる仕組みがほしいな 百々さん 条件分岐といえばif文だよネッ 羽地さん コクリ 地井さん
固定日時を返す実装の追加 public interface DateTimeProvider { LocalDateTime now(); } インタフェースの抽出 @Component
public class SystemDateTimeProvider implements DateTimeProvider { @Override public LocalDateTime now() { return LocalDateTime.now(); } } public class FixedDateTimeProvider implements DateTimeProvider { @Override public LocalDateTime now() { return LocalDateTime.of(2026, 10, 19, 19, 0, 0, 0); } }
Beanをどう切り替える? 2つのBeanの両方に@Componentをつける場合(=両方Bean登録する)、 依存元全てで次のようなif文が必要になる public NotificationService(@Value("${app.datetime.type}") String type, SystemDateTimeProvider systemDateTimeProvider,
FixedDateTimeProvider fixedDateTimeProvider) { if (type != null && type.equalsIgnoreCase("fixed")) { this.dateTimeProvider = fixedDateTimeProvider; 冗長 } else { 依存が増えてる this.dateTimeProvider = systemDateTimeProvider; } } public NotificationService(DateTimeProvider dateTimeProvider) { this.dateTimeProvider = dateTimeProvider; このままだと } Bean重複で起動時にエラー
@BeanによるBean登録 @Configurationをつけたクラス内で、@Beanをつけたファクトリメソッドを 作成することでBean登録が可能 メソッドの中で条件分岐することで実装を切り替えることができる @Configuration public class DateTimeConfiguration
{ @Bean public DateTimeProvider dateTimeProvider(@Value("${app.datetime.type}") String type) { if (type != null && type.equalsIgnoreCase("fixed")) { return new FixedDateTimeProvider(); } else { プロパティで実装を切り替え return new SystemDateTimeProvider(); } } } ※Configurationのクラスもコンポーネントスキャン対象のパッケージに置くか、 @Importで明示的にインポートする必要がある(後述)
他のプロジェクトでも使えるように ライブラリにしろッ 百々さん エッ!! 地井さん ファイルを移動するだけだし大丈夫だよッ 羽地さん
ライブラリにしたいけど・・・ 別パッケージに変更した上でライブラリに切り出してみる パッケージが変わったことで、ライブラリの中のDateTimeConfigurationが コンポーネントスキャンで読み込まれなくなってしまう アプリ io.github.rshindo.hogeservice この下のパッケージしかスキャンしない ライブラリ
io.github.rshindo.library DateTimeConfiguration スキャン対象にならない
@ImportでConfigurationをインポート コンポーネントスキャン対象のクラス(@SpringBootApplicationをつけたクラスなど) にConfigurationクラスを指定した@Importをつけると、パッケージに関係なくConfigを インポートすることができる なお、Configurationクラスに別のConfigクラスの@Importをつけることで、多重にイン ポートしたり、複数のConfigクラスをグルーピングすることができる @SpringBootApplication @Import(DateTimeConfiguration.class)
public class HogeServiceApplication { static void main(String[] args) { SpringApplication.run(HogeServiceApplication.class, args); } } しかし・・・
いちいち@Importをつけるのが めんどくさいんだよォーーーッ 百々さん
@Importをいちいち書くの面倒問題 クライアントが少数であれば問題ないが、クライアントが多数であったり、 同様のライブラリが多数あると@Importを書く手間が増える Auto Configurationっていう仕組みで 解決できるらしいよ! 羽地さん わァ…ァ… 地井さん
Auto Configurationとは 一言でいうと、Configurationを自動読み込みする仕組み クラスパスにライブラリがあるだけで自動的にConfigurationを 読み込んでBeanの登録をやってくれる @SpringBootApplication @Import(DateTimeConfiguration.class) ←これが要らなくなる
public class HogeServiceApplication { static void main(String[] args) { SpringApplication.run(HogeServiceApplication.class, args); } }
Auto Configurationの作り方 ① @Configurationを@AutoConfigurationに変更する ※必須ではないけど推奨 • Auto Configurationであることが明確に分かるようになるほか、 他のAuto Configurationと比べた適用順序を属性で指定できるといった
メリットがある @AutoConfiguration public class DateTimeConfiguration { @Bean public DateTimeProvider dateTimeProvider(@Value("${app.datetime.type}") String type) { if (type != null && type.equalsIgnoreCase("fixed")) { return new FixedDateTimeProvider(); } else { return new SystemDateTimeProvider(); } } }
Auto Configurationの作り方 ② META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports を作成し、中に対象のAutoConfigurationクラスのFQDNを書く # 一応コメントも書ける io.github.rshindo.library.DateTimeConfiguration # 複数のAutoConfigurationを書くことも可能
# io.github.rshindo.library.WebClientConfiguration META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
Auto Configurationの作り方 ③ Spring Bootアプリを起動すると、次のようなデバッグログ が出力される 2026-10-14T21:32:32.887+09:00 DEBUG 77292 ---
[hoge-project] [main] .s.b.a.l.ConditionEvaluationReportLogger : ============================ CONDITIONS EVALUATION REPORT ============================ (中略) Unconditional classes: ---------------------- io.github.rshindo.library.DateTimeConfiguration ….
if文じゃないやり方で、プロパティで実装を 切り替えられるようにしろッ 百々さん (Spring Boot Referenceを見せる) 地井さん @ConditionalOnProperty を使えば いいんだッ!!
羽地さん
@ConditionalOnProperty プロパティの値ごとにBeanを切り替えることができる app.datetime.type=fixed の場合にマッチする @AutoConfiguration public class DateTimeConfiguration {
@Bean @ConditionalOnProperty(name = "app.datetime.type", havingValue = "fixed") public DateTimeProvider fixedDateTimeProvider() { return new FixedDateTimeProvider(); } @Bean @ConditionalOnProperty(name = "app.datetime.type", havingValue = "system", matchIfMissing = true) public DateTimeProvider systemDateTimeProvider() { return new SystemDateTimeProvider(); app.datetime.type=system または } プロパティキーがない場合にマッチする } ※ただし空文字はマッチしない
@ConditionalOnMissingBean 他に有効なBeanがない場合に有効になる(つまりデフォルト) アプリ側のBean定義を優先したい場合にも使える @AutoConfiguration public class DateTimeConfiguration {
@Bean @ConditionalOnProperty(name = "app.datetime.type", havingValue = "fixed") public DateTimeProvider fixedDateTimeProvider() { return new FixedDateTimeProvider(); 他のBeanがない場合のデフォルトになる } @Bean @ConditionalOnMissingBean(DateTimeProvider.class) public DateTimeProvider systemDateTimeProvider() { return new SystemDateTimeProvider(); } }
その他の@ConditionalOn〜(一例) ConditionalOnBean ConditionalOnBooleanProperty ConditionalOnClass ConditionalOnCloudPlatform
ConditionalOnExpression ConditionalOnJava ConditionalOnWebApplication
Tips @ConditionalOn〜 はクラスにもつけられる @AutoConfiguration JdbcClientのBeanがある場合のみ有効 @ConditionalOnBean(JdbcClient.class) public class InvoiceRepositoryConfiguration
{ … } @ConditionalOnMissingBeanは基本的にはクラスレベルでつけておくか、 全てのBeanメソッドにつける アプリ側のBean登録が優先されないと、カスタマイズ性が悪くて 使いづらいライブラリになるぞ!
Auto Configurationってすごく べんりなんだネー 羽地さん エヘヘ・・・ 地井さん
Auto Configurationを読んでみよう! ここまでの知識でSpring Bootが提供しているAuto Configurationのコードを読むことができる ほとんどが@ConditionalOn〜と@Importの組み合わせ (例)
spring-boot-starter-jdbc のJdbcClientのBean定義 @AutoConfiguration(after = JdbcTemplateAutoConfiguration.class) @ConditionalOnSingleCandidate(NamedParameterJdbcTemplate.class) @ConditionalOnMissingBean(JdbcClient.class) @Import(DatabaseInitializationDependencyConfigurer.class) public final class JdbcClientAutoConfiguration { @Bean JdbcClient jdbcClient(NamedParameterJdbcTemplate jdbcTemplate) { return JdbcClient.create(jdbcTemplate); } }
Auto Configurationを読んでみよう! どこにBean定義があるか見つからないときの手段として、 Actuatorのconditionsエンドポイントで調べることができる { "contexts": { "hoge-project": {
"negativeMatches": { "DateTimeConfiguration#fixedDateTimeProvider": { "notMatched": [ { "condition": "OnPropertyCondition", "message": "@ConditionalOnProperty (app.datetime.type=fixed) found different value in property 'app.datetime.type'" } ], "matched": [] },
まとめ Bean登録の方法は、@Componentを使ったコンポーネントスキャンと @Beanを使ったファクトリメソッドがある @ImportでConfigurationをインポートできる Auto Configurationで@Importなしで自動読み込みできる
@ConditionalOn〜でBean登録の条件分岐ができる Spring Bootは黒魔術じゃないよ!(個人差があります)