Upgrade to Pro — share decks privately, control downloads, hide ads and more …

プロになるためのSpring上級知識 #jsug / advanced-spring-for-professionals

5dbaf4015e7f249ab21b195ced8e9e46?s=47 Masatoshi Tada
December 02, 2021

プロになるためのSpring上級知識 #jsug / advanced-spring-for-professionals

動画はこちら→ https://www.youtube.com/watch?v=c5ha8FmdNmw

Spring Fest 2021の資料です。

DIコンテナなどSpringの基礎知識が既にある方を対象に、上級者へステップアップするために必要な発展的知識を解説します。
このセッションを聞けば、プロジェクトをリードできるエンジニアになれること間違いなし!かも!?
・DIコンテナの要点復習
・同じ型のBeanが複数あるとどうなる?
・Java Configクラスを分割・統合するには?
・環境によって設定値やBeanを変更するには?
・Beanはどうやって作られる?

5dbaf4015e7f249ab21b195ced8e9e46?s=128

Masatoshi Tada

December 02, 2021
Tweet

More Decks by Masatoshi Tada

Other Decks in Technology

Transcript

  1. ϓϩʹͳΔͨΊͷ 4QSJOH্ڃ஌ࣝ ג ΫϨσΟηκϯଟాਅහ ೥݄೔ 4QSJOH'FTU 1

  2. ͜ͷηογϣϯʹ͍ͭͯ ▸ 4QSJOH্ڃऀʹඞਢͱͳΔɺ%*ίϯςφؔ࿈ͷ 
 ൃలతͳ஌ࣝʹ͍ͭͯղઆ͠·͢ ▸ ͜ͷηογϣϯ͸ʲதڃऀ޲͚ʳͰ͢ ▸ 4QSJOHͷ%*ίϯςφͳͲʹ͍ͭͯ͸ɺ 


    ͋Δఔ౓஌͍ͬͯΔ͜ͱΛલఏʹղઆ͠·͢ ▸ 4QSJOH#PPUΛར༻͍ͯ͠ͳ͍͜ͱΛલఏͱ͠·͢ ▸ ར༻࣌ͷҧ͍͸ඞཁʹԠͯ͡ղઆ͠·͢ 2
  3. ͜ͷηογϣϯͷલఏ஌ࣝ ▸ 4QSJOH'FTUͷ͜ͷηογϣϯ 3 IUUQTZPVUVCF-(UEQTN.GW*

  4. ࣗݾ঺հ 4 ▸ ଟాਅහ !TVLF@NBTB  ▸ ΫϨδοτΧʔυؔ࿈ͷ 
 γεςϜΛ࡞ͬͯΔ

    
 +BWBΤϯδχΞ ▸ ݩɾݚमτϨʔφʔ ▸ +46(ελοϑ
  5. ໨࣍ ᶃ %*ίϯςφͷཁ఺෮श ᶄ ಉ͡ܕͷ#FBO͕ෳ਺͋ΔͱͲ͏ͳΔʁ ᶅ +BWB$PO fi HΫϥεΛ෼ׂɾ౷߹͢Δʹ͸ʁ ᶆ

    ؀ڥʹΑͬͯ#FBO΍ઃఆ஋Λมߋ͢Δʹ͸ʁ ᶇ #FBO͸Ͳ͏΍ͬͯ࡞ΒΕΔʁ 5
  6. ໨࣍ ᶃ %*ίϯςφͷཁ఺෮श ᶄ ಉ͡ܕͷ#FBO͕ෳ਺͋ΔͱͲ͏ͳΔʁ ᶅ +BWB$PO fi HΫϥεΛ෼ׂɾ౷߹͢Δʹ͸ʁ ᶆ

    ؀ڥʹΑͬͯ#FBO΍ઃఆ஋Λมߋ͢Δʹ͸ʁ ᶇ #FBO͸Ͳ͏΍ͬͯ࡞ΒΕΔʁ 6
  7. 4QSJOH͸ίϯςφΛ͍࣋ͬͯΔ ▸ ίϯςφʹΠϯελϯεͷೖΕ෺ ▸ #FBOʹίϯςφͰ؅ཧ͞ΕͨΠϯελϯε 7 ίϯςφ #FBO #FBO #FBO

    #FBO #FBO ˞ʮΠϯελϯεʯͱ͸ɺ 
 ɹ΋ͪΖΜ+BWBͷΠϯελϯεͷ 
 ɹ͜ͱͰ͢ ඞཁʹԠͯ͡ 
 औΓग़ͯ͠࢖͏
  8. #FBOΛఆٛ͢Δํ๏ ᶃ ίϯϙʔωϯτεΩϟϯ ᶄ +BWB$PO fi H ᶅ ؔ਺ܕ#FBOఆٛ ࠓճ͸ׂѪ

     ᶆ 9.- ࠓճ͸ׂѪ 8
  9. #FBOఆٛํ๏ᶃίϯϙʔωϯτεΩϟϯ ▸ ίϯϙʔωϯτεΩϟϯ 
 ʹࢦఆ͞Εͨύοέʔδ͔Β@Component͕ 
 ɹ෇͍ͨΫϥεΛ୳͢ ▸ ݟ͚ͭͨΒΠϯελϯεԽˠίϯςφʹอଘ 9

  10. #FBOఆٛํ๏ᶃίϯϙʔωϯτεΩϟϯ ▸ ӈهͷΞϊςʔγϣϯΛ 
 Ϋϥεʹ෇͚Δͱɺ 
 @ComponentΛ෇͚ͨ 
 ͜ͱͱಉ͡ʹͳΔ ▸

    Ϋϥεͷ໾ׂʹԠͯ͡ 
 ม͑Δ 10 @Repository @Service @Controller @RestController @Configuration @ControllerAdvice @RestControllerAdvice ɾɾɾ ˞͜ΕΒͷΞϊςʔγϣϯͷιʔείʔυΛಡΉͱɺ 
 ɹ@Component͕෇͍͍ͯΔ͜ͱ͕෼͔Γ·͢ +BWB$PO fi H΋ #FBOʂ
  11. #FBOఆٛํ๏ᶃίϯϙʔωϯτεΩϟϯ ▸ #FBOͱ͍ͨ͠Ϋϥε 11 package com.example; @Component public class Hoge

    { ... } @Configuration @ComponentScan(basePackages = "com.example") public class AppConfig {} ▸ ઃఆΫϥε +BWB$PO fi H @Component͕ 
 ෇͍ͨΫϥεΛ 
 ୳͢ύοέʔδ
  12. #FBOఆٛํ๏ᶄ+BWB$PO fi H ▸ +BWB$PO fi HΫϥεʹϝιουΛ࡞੒͠ɺ 
 @BeanΛ෇Ճ͢Δ 


    ˠϝιουͷ໭Γ஋͕#FBOʹͳΔ 12 !$PNQPOFOU4DBO͸ෆཁ @Configuration public class AppConfig { @Bean public Hoge hoge() { return new Hoge(); } } !$PNQPOFOU͸ෆཁ public class Hoge { ... }
  13. #FBO*%ͱ͸ ▸ ֤#FBOΛࣝผ͢ΔͨΊͷ*% ▸ @ComponentͰ#FBOఆٛͨ͠৔߹ɺ 
 ʮΫϥε໊ͷ಄จࣈΛখจࣈʹͨ͠΋ͷʯ 
 ͕#FBO*% ▸

    @BeanͰ#FBOఆٛͨ͠৔߹ɺ 
 ϝιου໊͕#FBO*% 13
  14. #FBO*%ͱ͸ 14 @Component public class FooBar { ... } @Component("foo_bar")

    public class FooBar { ... } @Configuration public class FooConfig { @Bean public FooBar fooBar() { ... } @Bean(name = "foo_bar") public FooBar fooBar2() { ... } } fooBar foo_bar fooBar foo_bar #FBO*%
  15. ίϯςφΛ࡞Δɾ#FBOΛऔಘ͢Δ ▸ +BWB$PO fi HΫϥεΛࢦఆͯ͠ 
 ApplicationContext ίϯςφ Λ࡞੒ ▸

    ίϯϙʔωϯτεΩϟϯɾ+BWB$PO fi HͲͪΒͰ΋ڞ௨ ▸ getBean()Ͱ#FBOΛऔಘͰ͖Δ 15 ίϯςφͷ࡞੒ ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); #FBOΛ%*ίϯςφ͔ΒऔಘʢҾ਺͸ཉ͍͠#FBOͷσʔλܕʣ Hoge hoge = context.getBean(Hoge.class);
  16. 4QSJOH#PPUͷ৔߹ 16 ApplicationContext context = SpringApplication.run(AppConfig.class, args); Α͘main()ϝιουʹ 
 ॻ͔Ε͍ͯΔॲཧͰ͢Ͷʂ

  17. %* ▸ ίϯετϥΫλʹ@AutowiredΛ෇Ճ͠ɺ 
 Ҿ਺ʹཉ͍͠#FBOΛࢦఆ ▸ ίϯςφ͕ద੾ͳ#FBOΛҾ਺ʹ୅ೖͯ͘͠ΕΔ ▸ Ϋϥε಺ʹίϯετϥΫλ͕ͭͷ৔߹ɺ@Autowired͸লུՄ 17

    @Component public class Hoge { private final Fuga fuga; @Autowired public Hoge(Fuga fuga) { this.fuga = fuga; } } ίϯςφ Hoge Fuga %* %*
  18. ͍ΖΜͳ%* ▸ ίϯετϥΫλΠϯδΣΫγϣϯ 18 @Component public class Hoge { private

    final Fuga fuga; @Autowired public Hoge(Fuga fuga) { this.fuga = fuga; } } @Component public class Hoge { private Fuga fuga; @Autowired public setFuga(Fuga fuga) { this.fuga = fuga; } } @Component public class Hoge { @Autowired Fuga fuga; } །ҰHogeΛมߋෆೳʹ Ͱ͖ΔͷͰ ίϯετϥΫλ ΠϯδΣΫγϣϯਪ঑ ˞มߋෆೳ Πϛϡʔλϒϧ ʹϑΟʔϧυͷ஋Λॻ׵ෆՄೳ ▸ ϑΟʔϧυΠϯδΣΫγϣϯ ▸ ϝιουΠϯδΣΫγϣϯ
  19. ͜ͷষͷ·ͱΊ ▸ ίϯςφʹΠϯελϯε #FBO ͷೖΕ෺ ▸ ίϯϙʔωϯτεΩϟϯ ▸ @ComponentͰ#FBOʹ͢ΔΫϥεΛࢦఆ ▸

    @ComponentScanͰ୳͢ൣғΛࢦఆ ▸ +BWB$PO fi H ▸ @BeanΛ෇Ճͨ͠ϝιουͷ໭Γ஋͕#FBOʹͳΔ ▸ %* ▸ ίϯετϥΫλͳͲʹ@AutowiredΛ෇Ճ 19
  20. ໨࣍ ᶃ %*ίϯςφͷཁ఺෮श ᶄ ಉ͡ܕͷ#FBO͕ෳ਺͋ΔͱͲ͏ͳΔʁ ᶅ +BWB$PO fi HΫϥεΛ෼ׂɾ౷߹͢Δʹ͸ʁ ᶆ

    ؀ڥʹΑͬͯ#FBO΍ઃఆ஋Λมߋ͢Δʹ͸ʁ ᶇ #FBO͸Ͳ͏΍ͬͯ࡞ΒΕΔʁ 20
  21. Ͳ͏ͳΔʁ 21 @Component public class FooImpl1 implements Foo { ...

    } @Component public class FooImpl2 implements Foo { ... } @Component public class Bar { public Bar(Foo foo) { ... } } ܕ'PPʹ߹க͢Δ#FBO͕ͭ ˠྫ֎ൃੜʂʂ
  22. ղܾํ๏ ᶃ @QualifierΛར༻ ᶄ @PrimaryΛར༻ ᶅ %*͢ΔܕΛม͑Δ 22

  23. ᶃ!2VBMJ fi FSΛར༻ 23 @Component // Bean ID͸"fooImpl1" public class

    FooImpl1 implements Foo { ... } @Component // Bean ID͸"fooImpl2" public class FooImpl2 implements Foo { ... } @Component public class Bar { private final Foo foo; public Bar(@Qualifier("fooImpl1") Foo foo) { ... } } %*͍ͨ͠#FBOͷ#FBO*%Λࢦఆ
  24. !2VBMJ fi FSͷ΋͏ͭͷ࢖͍ํ 24 @Retention(RUNTIME) @Target({METHOD, TYPE, PARAMETER, FIELD}) @Qualifier

    public @interface Foo1 { ... } @Retention(RUNTIME) @Target({METHOD, TYPE, PARAMETER, FIELD}) @Qualifier public @interface Foo2 { ... } ▸ @QualifierΛ෇Ճͨ͠ಠࣗΞϊςʔγϣϯΛ 
 ͭ࡞੒
  25. !2VBMJ fi FSͷ΋͏ͭͷ࢖͍ํ 25 @Component @Foo1 public class FooImpl1 implements

    Foo { ... } @Component @Foo2 public class FooImpl2 implements Foo { ... } @Component public class Bar { public Bar(@Foo1 Foo foo) { ... } } ▸ ಠࣗΞϊςʔγϣϯΛ#FBOఆٛՕॴɾ%*Օॴͷ ྆ํʹ෇Ճ FooImpl1͕%*͞ΕΔ
  26. !2VBMJ fi FSͷ࢖͍ॴ ▸ কདྷతʹ%*͢Δ#FBOͷܕ͕มΘΔՄೳੑ͕͋Δ ৔߹΍ɺܕͰͷ۠ผ͕೉͍͠৔߹ʹ࢖͏ ▸ #FBO*%ΛจࣈྻͰϋʔυίʔυ͢ΔΑΓ΋ɺ 
 ಠࣗΞϊςʔγϣϯΛ࢖͏

    26
  27. ᶄ!1SJNBSZΛར༻ 27 @Component @Primary public class FooImpl1 implements Foo {

    ... } @Component public class FooImpl2 implements Foo { ... } @Component public class Bar { public Bar(Foo foo) { ... } } FooImpl1͕%*͞ΕΔ ʢFooImpl2Λ%*͍ͨ͠৔߹͸ 
 @QualifierΛར༻ʣ
  28. !1SJNBSZͷ࢖͍ॴ ▸ ϓϩμΫγϣϯίʔυͰ͸ͳΔ΂͘࢖Θͳ͍ ▸ @QualifierͳͲͰ໌ࣔతʹࢦఆͨ͠΄͏͕ؒҧ͍͕গͳ͍ ▸ ޙͰͭ໨ͷ#FBOΛ௥Ճ͢Δ͜ͱʹͳͬͨࡍɺͭ໨ͷ#FBO ͕େྔʹ͋ͬͯमਖ਼ՕॴΛগͳ͍ͨ͘͠৔߹͸க͠ํͳ͔͠΋ ▸ ςετίʔυͰελϒΛ%*͢ΔͨΊʹ࢖͏

    28 @Configuration public class TestConfig { @Bean @Primary public Foo foo { return new StubFoo(); } } #BSͷςετ࣌ʹ ίϨ͕%*͞ΕΔ
  29. ᶅ%*͢ΔܕΛม͑Δ 29 @Component public class FooImpl1 implements Foo { ...

    } @Component public class FooImpl2 implements Foo { ... } @Component public class Bar { public Bar(FooImpl1 foo) { ... } } %*͍ͨ͠#FBOͷܕΛ໌ࣔ
  30. ܕͷ࢖͍ॴ ▸ ՄೳͳݶΓ͜ͷํ๏Λ࢖͏ ▸ Ξϊςʔγϣϯͩͱ෇͚๨ΕͷϦεΫ͕ߴ͍ 30

  31. ͜ͷষͷ·ͱΊ ▸ ಉ͡ܕͷ#FBO͕͋ͬͨΒ ▸ @QualifierΛར༻ ▸ @PrimaryΛར༻ ▸ %*͢ΔܕΛม͑Δ ▸

    ՄೳͳݶΓܕͰ൑ผɻ࣍఺Ͱ@Qualifierɻ 
 @Primary͸ςετͷΈɻ 31
  32. ໨࣍ ᶃ %*ίϯςφͷཁ఺෮श ᶄ ಉ͡ܕͷ#FBO͕ෳ਺͋ΔͱͲ͏ͳΔʁ ᶅ +BWB$PO fi HΫϥεΛ෼ׂɾ౷߹͢Δʹ͸ʁ ᶆ

    ؀ڥʹΑͬͯ#FBO΍ઃఆ஋Λมߋ͢Δʹ͸ʁ ᶇ #FBO͸Ͳ͏΍ͬͯ࡞ΒΕΔʁ 32
  33. +BWB$PO fi Hͷ෼ׂ 33 ▸ ͭͷ+BWB$PO fi Hʹ͢΂ͯͷ#FBOఆٛΛॻ͘ͱ 
 Ϋϥε͕ංେԽ͢Δ

    
 ˠ+BWB$PO fi HΛ෼ׂ͢Δ ▸ ྫ͑͹ԼهͷΑ͏ʹ෼ׂ͢Δ ᶃ 4QSJOH.7$༻$PO fi H ᶄ ϏδωεϩδοΫʴτϥϯβΫγϣϯ༻$PO fi H ᶅ σʔλιʔεʴ03Ϛούʔ༻$PO fi H
  34. ෼ׂͨ͠+BWB$PO fi HΛ͢΂ͯ࢖͏ํ๏ ᶃ @ImportͰ·ͱΊΔ ᶄ ίϯϙʔωϯτεΩϟϯ഑Լʹஔ͘ ᶅ ApplicationContextͷίϯετϥΫλʹ 


    ͢΂ͯࢦఆ͢Δ 34
  35. ᶃ!*NQPSUͰ·ͱΊΔ 35 @Import(Config2.class) @Configuration public class Config1 { ... }

    @Configuration public class Config2 { ... } ApplicationContext context = new AnnotationConfigApplicationContext(Config1.class); $PO fi Hʹ$PO fi HΛ߹ମ $PO fi HͷΈΛࢦఆ
  36. <ൃల>!&OBCMF9YY͸!*NQPSU ▸ @EnableWebMvcͳͲͷΞϊςʔγϣϯ͸ɺ 
 ࣮͸@ImportͰطଘͷ+BWB$PO fi HΛ 
 ߹ମ͍ͤͯ͞Δ 36

  37. ᶄίϯϙʔωϯτεΩϟϯ഑Լʹஔ͘ 37 @Configuration @ComponentScan(basePackages = "com.example") public class Config1 {

    ... } package com.example.foo; @Configuration public class Config2 { ... } εΩϟϯ഑Լʹஔ͚͹ ͦͷ+BWB$PO fi H͸࢖ΘΕΔ ApplicationContext context = new AnnotationConfigApplicationContext(Config1.class); $PO fi HͷΈΛࢦఆ
  38. ᶅ"QQMJDBUJPO$POUFYUͷίϯετϥΫλʹ 
 ɹ͢΂ͯࢦఆ͢Δ 38 ApplicationContext context = new AnnotationConfigApplicationContext( Config1.class,

    Config2.class); @Configuration public class Config1 { ... } @Configuration public class Config2 { ... } Մม௕Ҿ਺Ͱશ+BWB$PO fi HΛࢦఆ
  39. ࢖͍ॴ ▸ ݸਓతʹ͸΄ͱΜͲ 
 ʮᶄίϯϙʔωϯτεΩϟϯʯͰࡁ·ͤΔ ▸ ಛʹ4QSJOH#PPUͷ৔߹ ▸ ಛఆͷ+BWB$PO fi

    H͚ͩΛ࢖͍͍ͨ৔߹͸ɺ 
 ίϯϙʔωϯτεΩϟϯ֎ʹ࡞ͬͯ 
 ʮᶃ@ImportʯΛ࢖͏ 39
  40. ͜ͷষͷ·ͱΊ ▸ +BWB$PO fi H͸ద੾ʹ෼ׂ͢Δ ▸ ෼ׂͨ͠+BWB$PO fi HΛ·ͱΊΔํ๏͸ ᶃ

    @Import ᶄ ίϯϙʔωϯτεΩϟϯ ᶅ ApplicationContextͷҾ਺ ▸ ΄΅ᶄίϯϙʔωϯτεΩϟϯͰࡁ·ͤͯ0, 40
  41. ໨࣍ ᶃ %*ίϯςφͷཁ఺෮श ᶄ ಉ͡ܕͷ#FBO͕ෳ਺͋ΔͱͲ͏ͳΔʁ ᶅ +BWB$PO fi HΫϥεΛ෼ׂɾ౷߹͢Δʹ͸ʁ ᶆ

    ؀ڥʹΑͬͯ#FBO΍ઃఆ஋Λมߋ͢Δʹ͸ʁ ᶇ #FBO͸Ͳ͏΍ͬͯ࡞ΒΕΔʁ 41
  42. ؀ڥʹΑͬͯ#FBOΛ੾Γସ͍͑ͨʂ ▸ ྫɿDataSourceΛςετ؀ڥͱຊ൪؀ڥͰ੾ସ 42 @Configuration public class AppConfig { @Bean

    public DataSource testDataSource() { return ૊ΈࠐΈσʔλϕʔε; } @Bean public DataSource productionDataSource() { return APαʔόʔ͔Βऔಘͨ͠σʔλιʔε; } } ͜ͷ··ͩͱDataSourceͷ %*࣌ʹ࣮ߦ࣌ྫ֎ ͜ͷ··ͩͱDataSourceͷ %*࣌ʹ࣮ߦ࣌ྫ֎
  43. ϓϩϑΝΠϧΛ࢖͏ ▸ ϓϩϑΝΠϧʹ#FBOͷάϧʔϓ ▸ @ProfileͰ೚ҙͷϓϩϑΝΠϧ໊Λࢦఆ ▸ ؀ڥม਺SPRING_PROFILES_ACTIVEͰ 
 ࣮ߦ࣌ͷϓϩϑΝΠϧΛࢦఆ 


    ˠࢦఆͨ͠ϓϩϑΝΠϧͷ#FBO͕༗ޮԽ͞ΕΔ 43
  44. ϓϩϑΝΠϧΛ࢖͏ 44 @Configuration public class AppConfig { @Bean @Profile("test") public

    DataSource testDataSource() { ... } @Bean @Profile("production") public DataSource productionDataSource() { ... } } $ export SPRING_PROFILES_ACTIVE=test $ mvn compile exec:java -DmainClass=com.example.Main testDataSourceͷΈ ༗ޮԽ͞ΕΔ
  45. ϓϩϑΝΠϧΛ࢖͏ 45 @Configuration @Profile("test") public class TestConfig { @Bean public

    DataSource testDataSource() { ... } } @Configuration @Profile("production") public class ProductionConfig { @Bean public DataSource productionDataSource() { ... } } ▸ +BWB$PO fi Hʹ΋@ProfileΛ෇ՃͰ͖Δ ࣮ߦ࣌ʹUFTUϓϩϑΝΠϧ ࢦఆͰ༗ޮԽ͞ΕΔ ࣮ߦ࣌ʹQSPEVDUJPOϓϩϑΝΠϧ ࢦఆͰ༗ޮԽ͞ΕΔ
  46. ओͳ࣮ߦ࣌ϓϩϑΝΠϧࢦఆํ๏ ᶃ +6OJUςετ ▸ @ActiveProfiles("test") ᶄ +7.γεςϜϓϩύςΟ ▸ java -Dspring.profiles.active=test

    ... ᶅ ؀ڥม਺ ▸ export SPRING_PROFILES_ACTIVE=test 46 ௿ ߴ ༏ઌॱҐ ※શͯͷํ๏Ͱෳ਺ͷϓϩϑΝΠϧ໊ΛࢦఆՄೳʢΧϯϚ۠੾Γʣ ଟ༻͢ΔͱNWOUFTUͰͷ 
 ςετ࣮ߦ͕࣌ؒ௕͘ͳΔͷͰ஫ҙ 
 %*ίϯςφ͕࠶࡞੒͞ΕΔͨΊ
  47. ϓϩϑΝΠϧͷ஫ҙ఺ ▸ ϓϩϑΝΠϧʹଐ͍ͯ͠ͳ͍#FBO͸ 
 ࣮ߦ࣌ʹͲͷϓϩϑΝΠϧΛࢦఆͯ͠΋ 
 ༗ޮԽ͞ΕΔ 47 @Configuration public

    class AppConfig { @Bean public Sample sample() { ... } @Bean @Profile("test") public Sample testSample() { ... } } ͜ͷ#FBO͸ͲΜͳϓϩϑΝΠϧΛ ࢦఆͯ͠΋࢖ΘΕΔ ͜ͷ#FBO͸UFTUϓϩϑΝΠϧ 
 ࢦఆ࣌ͷΈ࢖ΘΕΔ
  48. ϓϩύςΟϑΝΠϧ͔Βઃఆ஋Λऔಘ 48 @Configuration @PropertySource("classpath:/sample.properties") public class AppConfig { ... }

    # src/main/resources/sample.properties sample.message=Hello! @Component public class Sample { public Sample( @Value("${sample.message}") String message) { ... } } \ϓϩύςΟ໊^Ͱऔಘ ͜ͷ৔߹ɺΫϥεύε্ͷઈରύε fi MF΍IUUQ΋ར༻Մೳ
  49. !7BMVFͰ஋ΛऔಘͰ͖Δओͳ৔ॴ ᶃ XFCYNMͷcontext-param ᶄ +7.γεςϜϓϩύςΟ ▸ java -Dxxx=yyy ᶅ ؀ڥม਺

    ᶆ ϓϩύςΟϑΝΠϧ 49 ௿ ߴ ༏ઌॱҐ
  50. ϓϩϑΝΠϧͰϓϩύςΟϑΝΠϧΛ੾Γସ͑Δ 50 @Configuration @PropertySource( "classpath:/sample-${SPRING_PROFILES_ACTIVE}.properties" ) public class AppConfig {

    ... } # src/main/resources/sample-test.properties sample.message=Hello Test! # src/main/resources/sample-production.properties sample.message=Hello Production! $ export SPRING_PROFILES_ACTIVE=test $ mvn compile exec:java -DmainClass=com.example.Main Hello Test! ϑΝΠϧ໊ʹϓϨʔεϗϧμʔΛؚΊΔ 4QSJOH#PPUͰ͸ඞཁͷແ͍ςΫχοΫ ޙड़
  51. 4QSJOH#PPUͷ৔߹ ▸ ઃఆ஋͸͢΂ͯBQQMJDBUJPOQSPQFSUJFTʹॻ͘ ▸ ಛఆͷϓϩϑΝΠϧͰͷΈར༻͢Δઃఆ஋͸ 
 BQQMJDBUJPOϓϩϑΝΠϧ໊QSPQFSUJFTʹॻ͘ ▸ ྫɿBQQMJDBUJPOUFTUQSPQFSUJFT 


    ɹɹBQQMJDBUJPOQSPEVDUJPOQSPQFSUJFT ▸ BQQMJDBUJPOQSPQFSUJFTͷ஋͸ɺ 
 ϓϩϑΝΠϧࢦఆͷ༗ແʹؔΘΒͣඞͣ࢖ΘΕΔ ▸ BQQMJDBUJPOQSPQFSUJFTͱ 
 BQQMJDBUJPOϓϩϑΝΠϧ໊QSPQFSUJFTʹಉ໊ͷઃఆ͕͋ͬͨΒɺ 
 ޙऀͷ΋ͷ͕࢖ΘΕΔ 51 @PropertySource 
 ෆཁ
  52. 4QSJOH#PPUͷ৔߹ ▸ 3FMBYFE#JOEJOH ▸ BQQMJDBUJPOQSPQFSUJFTͷfoo.barΛ 
 ؀ڥม਺ͷFOO_BARͰ্ॻ͖Մೳ 52

  53. 4QSJOH#PPUͷ৔߹ ▸ ϓϩύςΟ ͷ༏ઌॱҐ ͕ܾ·ͬͯ ͍Δ 53 https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.external-con fi g

    ΑΓҾ༻ ௿ ߴ ༏ઌॱҐ
  54. ͜ͷষͷ·ͱΊ ▸ @ProfileͰ#FBOΛάϧʔϓԽͰ͖Δ ▸ ࣮ߦ࣌ϓϩϑΝΠϧ໊ͷࢦఆํ๏͸͍Ζ͍Ζ ▸ @ActiveProfilesɺ-Dspring.profiles.activeɺ 
 ؀ڥม਺SPRING_PROFILES_ACTIVE ▸

    ϓϩύςΟϑΝΠϧ͸@PropertySourceͰࢦఆ ▸ ϑΝΠϧ໊ʹϓϨʔεϗϧμʔΛࢦఆ͢Δ͜ͱͰ؀ڥͰͷ੾ସՄೳ ▸ 4QSJOH#PPUͰ͸BQQMJDBUJPOQSPQFSUJFTʹઃఆΛॻ͘ ▸ 3FMBYFE#JOEJOH΍ઃఆͷ༏ઌॱҐ͸͓֮͑ͯ͘ 54
  55. ໨࣍ ᶃ %*ίϯςφͷཁ఺෮श ᶄ ಉ͡ܕͷ#FBO͕ෳ਺͋ΔͱͲ͏ͳΔʁ ᶅ +BWB$PO fi HΫϥεΛ෼ׂɾ౷߹͢Δʹ͸ʁ ᶆ

    ؀ڥʹΑͬͯ#FBO΍ઃఆ஋Λมߋ͢Δʹ͸ʁ ᶇ #FBO͸Ͳ͏΍ͬͯ࡞ΒΕΔʁ 55
  56. #FBOͷੜ੒ϓϩηε 56 ᶃ#FBOҰཡදΛͭ͘Δ ᶄ#FBOͷίϯετϥΫλΛ࣮ߦ͢Δ ᶅ#FBOʹޙॲཧΛߦ͏

  57. ᶃ#FBOҰཡදΛ࡞Δ 57 Ϋϥε໊ ID είʔϓ ஗Ԇ ґଘઌID com.Foo foo singleton

    false (ͳ͠) com.Bar bar prototype true foo ɾɾɾ ɾɾɾ ɾɾɾ ɾɾɾ ɾɾɾ ※͜ͷද͸ΠϝʔδͰ͢ɻਖ਼֬ͳ΋ͷͰ͸͋Γ·ͤΜɻ ▸ 👇ͷΑ͏ͳදΛ࡞Δ ▸ ࣮ମ͸ org.springframework.beans.factory.config.BeanDefinition
  58. ᶃ#FBOҰཡදΛ࡞Δ ▸ Ұཡද࡞੒ͷͨΊʹߦ͏͜ͱ  ίϯϙʔωϯτεΩϟϯ  +BWB$PO fi HΫϥε಺ͷ@Beanϝιουఆٛͷ֬ೝ ▸

    ͜ͷ࣌఺Ͱ͸ɺ 
 ·ͩΠϯελϯε͸ੜ੒͞Εͳ͍ʂ 58
  59. ᶃ#FBOҰཡදΛ࡞Δ ▸ #FBOҰཡද࡞੒ޙɺBeanFactoryPostProcessor͕ දͷҰ෦Λແཧ΍Γॻ͖׵͑Δ ▸ ओͳྫ ▸ PropertySourcesPlaceholderConfigurer ▸ @Valueͷ෦෼ΛϓϩύςΟ͔ΒಡΜͩ΋ͷʹஔ͖׵͑Δ

    ▸ LazyInitializationBeanFactoryPostProcessor ▸ 4QSJOH#PPUͷػೳʢspring.main.lazy-initialization=trueʣ ▸ શ#FBOͷ<஗Ԇ>ΛUSVFʹ͢Δ 59 ΠϯλϑΣʔε ࣮૷Ϋϥε ࣮૷Ϋϥε
  60. ᶄ#FBOͷίϯετϥΫλΛ࣮ߦ͢Δ ▸ #FBOҰཡදʹج͍ͮͯɺ 
 ίϯετϥΫλͰΠϯελϯεΛੜ੒͢Δ ▸ ͜ͷࡍɺίϯετϥΫλΠϯδΣΫγϣϯ΋ߦΘΕΔ ▸ Πϯελϯεੜ੒͸ɺґଘؔ܎ʹج͍ͮͯ 


    ਖ਼͍͠ॱ൪Ͱ࣮ߦ͞ΕΔ ▸ ྫɿ"͕#ʹґଘ͢Δˠ#ΛઌʹΠϯελϯεੜ੒͢Δ ▸ ϑΟʔϧυΠϯδΣΫγϣϯͱ 
 ϝιουΠϯδΣΫγϣϯ͸ɺ·ͩߦΘΕͳ͍ʂ 60
  61. ᶅ#FBOʹޙॲཧΛߦ͏ ▸ BeanPostProcessor͕#FBOΠϯελϯεʹޙॲཧΛࢪ͢ ▸ ओͳྫ ▸ AutowiredAnnotationBeanPostProcessor ▸ ϑΟʔϧυΠϯδΣΫγϣϯͱϝιουΠϯδΣΫγϣϯΛߦ͏ ▸

    CommonAnnotationBeanPostProcessor ▸ @PostConstruct͕෇Ճ͞ΕͨϝιουΛ࣮ߦ͢Δ ▸ AbstractAutoProxyCreator ▸ "01ͷͨΊͷϓϩΩγΠϯελϯεΛ࡞੒͢Δ 61 ΠϯλϑΣʔε ࣮૷Ϋϥε ࣮૷Ϋϥε ࣮૷Ϋϥε
  62. ิ଍ ▸ BeanFactoryPostProcessorɾ 
 BeanPostProcessorΛࣗ࡞͢Δ͜ͱ͸ك ▸ ֶश໨తͳΒΞϦ ▸ ੜ੒ϓϩηεΛ஌͍ͬͯΕ͹ɺڽͬͨ͜ͱΛ 


    ͢ΔࡍͷτϥϒϧΛղܾͰ͖Δ͔΋ ▸ ྫɿ#FBOੜ੒ॲཧʹ͸"01Λ͔͚ΒΕͳ͍ 
 ɹɹʢ·ͩϓϩΩγ͕࡞ΒΕΔલ͔ͩΒʣ 62
  63. ͜ͷষͷ·ͱΊ ᶃ #FBOҰཡදΛ࡞Δ ▸ ҰཡදΛ࡞੒ޙɺBeanFactoryPostProcessor͕ҰཡදͷҰ෦Λ ॻ͖׵͑Δ ᶄ #FBOͷίϯετϥΫλΛ࣮ߦ͢Δ ▸ ίϯετϥΫλΠϯδΣΫγϣϯ΋ߦΘΕΔ

    ᶅ #FBOʹޙॲཧΛߦ͏ ▸ BeanPostProcessor͕ϑΟʔϧυΠϯδΣΫγϣϯɾϝιουΠϯ δΣΫγϣϯɾ@PostConstructͷ࣮ߦɾϓϩΩγͷ࡞੒ͳͲΛߦ͏ 63
  64. ࠷ޙͷ·ͱΊ ▸ ಉ͡ܕͷ#FBO͸@Qualifierɾ@Primaryɾ 
 αϒΫϥεܕͳͲͰ൑ผͰ͖Δ ▸ ෼ׂͨ͠+BWB$PO fi H͸@Import΍ 


    ίϯϙʔωϯτεΩϟϯͰ౷߹͢Δ ▸ ઃఆ஋΍#FBOΛ؀ڥ͝ͱʹ࢖͍෼͚Δʹ͸ 
 ϓϩϑΝΠϧΛར༻͢Δ ▸ #FBOͷੜ੒ϓϩηε͸ 
 ᶃҰཡද࡞੒ˠᶄίϯετϥΫλ࣮ߦˠᶅޙॲཧ 64
  65. ߋͳΔֶशͷͨΊʹ ▸ 4QSJOHపఈೖ໳ʢᠳӭࣾʣ ▸ IUUQTXXXTIPFJTIBDPKQCPPLEFUBJM  ▸ 4QSJOHެࣜϦϑΝϨϯεʢಛʹ$PSFͷ෦෼ʣ ▸ <ӳޠ>IUUQTEPDTTQSJOHJPTQSJOHGSBNFXPSL

    EPDTDVSSFOUSFGFSFODFIUNMJOEFYIUNM ▸ <೔ຊޠ>IUUQTTQSJOHQMFJBEFTJPTQSJOH GSBNFXPSLEPDTDVSSFOUSFGFSFODFIUNM 65
  66. ▸ ͜ͷηογϣϯ͕ 
 ະདྷͷ4QSJOHϓϩϑΣογϣφϧͷ 
 ͓໾ʹཱͯΕ͹خ͍͠Ͱ͢ʂ 66