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

SpringはどうやってDIしているのか? #jjug_ccc

kariyayo
December 03, 2016

SpringはどうやってDIしているのか? #jjug_ccc

kariyayo

December 03, 2016
Tweet

More Decks by kariyayo

Other Decks in Programming

Transcript

  1. 4QSJOH$PSF5FDIOPMPHJFT • 5IF*P$DPOUBJOFS • 3FTPVSDFT • 7BMJEBUJPO %BUB#JOEJOH BOE5ZQF$PODFSTJPO •

    4QSJOH&YQSFTTJPO-BOHVBHF 4Q&-  • "TQFDU0SJFOUFE1SPHSBNNJOHXJUI4QSJOH • 4QSJOH"01"1*T 5
  2. 4QSJOH$PSF5FDIOPMPHJFT • 5IF*P$DPOUBJOFS • 3FTPVSDFT • 7BMJEBUJPO %BUB#JOEJOH BOE5ZQF$PODFSTJPO •

    4QSJOH&YQSFTTJPO-BOHVBHF 4Q&-  • "TQFDU0SJFOUFE1SPHSBNNJOHXJUI4QSJOH • 4QSJOH"01"1*T 6 今日話すのはここ
  3. 4QSJOHͷ%* 7 @Configuration @ComponentScan public class MyApp { public static

    void main(String[] args) { ApplicationContext c = new AnnotationConfigApplicationContext(MyApp.class); HelloWorldService helloWorldService = c.getBean(HelloWorldService.class); helloWorldService.helloWorld(); } }
  4. @Configuration @ComponentScan public class MyApp { public static void main(String[]

    args) { ApplicationContext c = new AnnotationConfigApplicationContext(MyApp.class); HelloWorldService helloWorldService = c.getBean(HelloWorldService.class); helloWorldService.helloWorld(); } } 4QSJOHͷ%* 8 @Configurationアノテーションがついてるクラス がBeanの設定を行うクラス (Bean = Springの管理対象となるインスタンス)
  5. @Configuration @ComponentScan public class MyApp { public static void main(String[]

    args) { ApplicationContext c = new AnnotationConfigApplicationContext(MyApp.class); HelloWorldService helloWorldService = c.getBean(HelloWorldService.class); helloWorldService.helloWorld(); } } 4QSJOHͷ%* 9 @ComponentScanアノテーションをつ けると、同パッケージ配下からBean 定義を探してくれる
  6. 10 @Component public class PrintService { public void print(String s)

    { System.out.println(s); } } @Component public class HelloWorldService { private PrintService printService; @AutoWired public HelloWorldService(PrintService printService) { this.printService = printService; } public void helloWorld() { printService.print("Hello, World!"); } }
  7. 11 @Component public class PrintService { public void print(String s)

    { System.out.println(s); } } @Component public class HelloWorldService { private PrintService printService; @AutoWired public HelloWorldService(PrintService printService) { this.printService = printService; } public void helloWorld() { printService.print("Hello, World!"); } } @Componentアノテーションがついて るとスキャンの対象となるBean定義 @Controllerや@Serviceなども同じ
  8. 12 @Component public class PrintService { public void print(String s)

    { System.out.println(s); } } @Component public class HelloWorldService { private PrintService printService; @AutoWired public HelloWorldService(PrintService printService) { this.printService = printService; } public void helloWorld() { printService.print("Hello, World!"); } } @AutoWireアノテーションをつけると BeanをDIしてくれる
  9. 14 • ͖ͬ͞ͷίʔυΛಡΜͰ͍͘ MyApp#main @Configuration @ComponentScan public class MyApp {

    public static void main(String[] args) { ApplicationContext c = new AnnotationConfigApplicationContext(MyApp.class); HelloWorldService helloWorldService = c.getBean(HelloWorldService.class); helloWorldService.helloWorld(); } }
  10. @Configuration @ComponentScan public class MyApp { public static void main(String[]

    args) { ApplicationContext c = new AnnotationConfigApplicationContext(MyApp.class); HelloWorldService helloWorldService = c.getBean(HelloWorldService.class); helloWorldService.helloWorld(); } } 16 MyApp#main コンストラクタにConfigurationアノ テーションがついてるクラスを渡す
  11. 18 public AnnotationConfigApplicationContext( Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }

    AnnotationConfigApplicationContext#new 引数なしのコンストラクタを呼ぶ
  12. 20 public AnnotationConfigApplicationContext( Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }

    AnnotationConfigApplicationContext#new registerメソッドにClass<MyApp> を渡してる
  13. 23  BOOPUBUFE$MBTT͔Β"OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛੜ੒  !$POEJUJPOBMΞϊςʔγϣϯͰ#FBOొ࿥ͷεΩοϓΛ൑ఆ  "OOPUBUJPO#FBO/BNF(FOFSBUPSͰ#FBOͷ໊લΛܾΊΔ  "OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛ#FBO%FpOJUJPO)PMEFSͰแΉ 

    ඞཁͰ͋Ε͹4DPQFE1SPYZʹؔ͢ΔॲཧΛ͢Δ  #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register
  14. 24  BOOPUBUFE$MBTT͔Β"OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛੜ੒  !$POEJUJPOBMΞϊςʔγϣϯͰ#FBOొ࿥ͷεΩοϓΛ൑ఆ  "OOPUBUJPO#FBO/BNF(FOFSBUPSͰ#FBOͷ໊લΛܾΊΔ  "OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛ#FBO%FpOJUJPO)PMEFSͰแΉ 

    ඞཁͰ͋Ε͹4DPQFE1SPYZʹؔ͢ΔॲཧΛ͢Δ  #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register Bean定義はBeanDefinitionで 表現される
  15. 25  BOOPUBUFE$MBTT͔Β"OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛੜ੒  !$POEJUJPOBMΞϊςʔγϣϯͰ#FBOొ࿥ͷεΩοϓΛ൑ఆ  "OOPUBUJPO#FBO/BNF(FOFSBUPSͰ#FBOͷ໊લΛܾΊΔ  "OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛ#FBO%FpOJUJPO)PMEFSͰแΉ 

    ඞཁͰ͋Ε͹4DPQFE1SPYZʹؔ͢ΔॲཧΛ͢Δ  #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register ConditionalアノテーションとConditionイ ンタフェースでBean登録をスキップできる http://docs.spring.io/spring/docs/current/spring-framework-reference/ htmlsingle/#beans-java-conditional
  16. 26  BOOPUBUFE$MBTT͔Β"OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛੜ੒  !$POEJUJPOBMΞϊςʔγϣϯͰ#FBOొ࿥ͷεΩοϓΛ൑ఆ  "OOPUBUJPO#FBO/BNF(FOFSBUPSͰ#FBOͷ໊લΛܾΊΔ  "OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛ#FBO%FpOJUJPO)PMEFSͰแΉ 

    ඞཁͰ͋Ε͹4DPQFE1SPYZʹؔ͢ΔॲཧΛ͢Δ  #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register 今回はAnnotationBeanNameGeneratorに よって決められる。 http://docs.spring.io/spring/docs/current/spring-framework-reference/ htmlsingle/#beans-scanning-name-generator
  17. 27  BOOPUBUFE$MBTT͔Β"OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛੜ੒  !$POEJUJPOBMΞϊςʔγϣϯͰ#FBOొ࿥ͷεΩοϓΛ൑ఆ  "OOPUBUJPO#FBO/BNF(FOFSBUPSͰ#FBOͷ໊લΛܾΊΔ  "OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛ#FBO%FpOJUJPO)PMEFSͰแΉ 

    ඞཁͰ͋Ε͹4DPQFE1SPYZʹؔ͢ΔॲཧΛ͢Δ  #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register BeanDefinitionHolderはBean名と BeanDefinitionを保持する
  18. 28  BOOPUBUFE$MBTT͔Β"OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛੜ੒  !$POEJUJPOBMΞϊςʔγϣϯͰ#FBOొ࿥ͷεΩοϓΛ൑ఆ  "OOPUBUJPO#FBO/BNF(FOFSBUPSͰ#FBOͷ໊લΛܾΊΔ  "OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛ#FBO%FpOJUJPO)PMEFSͰแΉ 

    ඞཁͰ͋Ε͹4DPQFE1SPYZʹؔ͢ΔॲཧΛ͢Δ  #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register AnnotationScopeMetadataResolverで@Scope アノテーションのproxyModeを読み取る http://docs.spring.io/spring/docs/current/spring-framework-reference/ htmlsingle/#beans-java-scoped-proxy
  19. 29  BOOPUBUFE$MBTT͔Β"OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛੜ੒  !$POEJUJPOBMΞϊςʔγϣϯͰ#FBOొ࿥ͷεΩοϓΛ൑ఆ  "OOPUBUJPO#FBO/BNF(FOFSBUPSͰ#FBOͷ໊લΛܾΊΔ  "OOPUBUFE(FOFSJD#FBO%FpOJUJPOΛ#FBO%FpOJUJPO)PMEFSͰแΉ 

    ඞཁͰ͋Ε͹4DPQFE1SPYZʹؔ͢ΔॲཧΛ͢Δ  #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register 次はここを見ていく
  20. 31 AnnotationConfigApplicationContext#new => #register => AnnotatedBeanDefinitionReader#register BeanDefinitionReaderUtils.registerBeanDefinition( definitionHolder, this.registry); •

    #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ さっき作ったMyAppクラスのBean定義 を保持するBeanDefinitionHolder
  21. 33 public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner =

    new ClassPathBeanDefinitionScanner(this); } AnnotationBeanDefinitionReaderの this.registryに、 AnnotationConfigApplicationContextが 代入される
  22. #FBOఆٛొ࿥ͷྲྀΕ 37 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry AnnotatedBean DefinitionReader

    AnnotatedGeneric BeanDefinition <ੜ੒> AnnotationConfigApplicationContextは BeanDefinitionRegistryのサブクラス
  23. #FBOఆٛొ࿥ͷྲྀΕ 38 AnnotationConfig ApplicationContext GenericApplication Context BeanDefinition Registry AnnotatedBean DefinitionReader

    AnnotatedGeneric BeanDefinition <ੜ੒> BeanDefinition ReaderUtils registerBeanDefinitionメソッド beanDefinitionHolderとregistryが引数
  24. 39 …=> AnnotatedBeanDefinitionReader#register => #registerBean
 => BeanDefinitionReaderUtils#registerBeanDefinition String beanName =

    definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); registryにBeanの名前と Bean定義を登録する
  25. ͭ·Γ 40 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry AnnotatedBean DefinitionReader

    AnnotatedGeneric BeanDefinition <ੜ੒> 1 N BeanDefinitionReaderUtils 経由で登録される BeanDefinitionR eaderUtils
  26. ͭ·Γ 41 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry AnnotatedBean DefinitionReader

    AnnotatedGeneric BeanDefinition <ੜ੒> 1 N 登録処理は registerBeanDefinitionメソッド BeanDefinitionR eaderUtils
  27. ͭ·Γ 46 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry AnnotatedBean DefinitionReader

    AnnotatedGeneric BeanDefinition <ੜ੒> 1 N BeanDefinitionR eaderUtils 登録するのは registerBeanDefinitionメソッド
  28. ͭ·Γ 47 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry AnnotatedBean DefinitionReader

    AnnotatedGeneric BeanDefinition <ੜ੒> 1 N DefaultListable BeanFactory registerBeanDefinitionメソッドに 委譲 BeanDefinitionR eaderUtils
  29. ͭ·Γ 48 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry AnnotatedBean DefinitionReader

    AnnotatedGeneric BeanDefinition <ੜ੒> 1 N DefaultListable BeanFactory BeanDefinitionはインスタンス変数の ConcurrentHashMapに保存される BeanDefinitionR eaderUtils
  30. ͜͜·ͰΛ੔ཧ 50 AnnotationConfig ApplicationContext Generic ApplicationContext AnnotatedBean DefinitionReader DefaultListable BeanFactory

    BeanDefinition ReaderUtils Class<MyApp> BeanDefinition Holder BeanDefinition Concurrent HashMap BeanDefinition BeanDefinition
  31. 52 public AnnotationConfigApplicationContext( Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }

    AnnotationConfigApplicationContext#new • ࣍͸ͬͪ͜ • SFGSFTIϝιου͸਌ΫϥεͰ͋Δ"CTUSBDU"QQMJDBUJPO$POUFYUͰ࣮ ૷͞Ε͍ͯΔ
  32. 53 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ
  33. 54 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ ログを出力したりインスタンス 変数を初期化したり
  34. 55 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ さっきも出てきた DefaultListableBeanFactoryインスタンスに 対していろいろ設定する
  35. 57 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ 次はここ
  36. 58 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ PostProcessorRegistrationDelegate に委譲する
  37. 60 J #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛ࣮૷ͨ͠Ϋϥεͷ QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZΛ࣮ߦ JJ #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛ࣮૷ͨ͠Ϋϥεͷ QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ JJJ #FBO'BDUPSZ1PTU1SPDFTTPSΛܧঝͨ͠Ϋϥεͷ QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ

    Springフレームワーク内部用? 今回のケースだと実は ConfigurationClassPostProcessorが 既に登録されている …=> AbstractApplicationContext#refresh => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
  38. 61 J #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛܧঝͨ͠Ϋϥεͷ QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZΛ࣮ߦ JJ #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛܧঝͨ͠Ϋϥεͷ QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ JJJ #FBO'BDUPSZ1PTU1SPDFTTPSΛܧঝͨ͠Ϋϥεͷ QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ

    Springフレームワーク内部用? 今回のケースだと実は ConfigurationClassPostProcessorが 既に登録されている AnnotatedBeanDefinitionReaderのコンストラクタで AnnotationConfigUtils.registerAnnotationConfigP rocessorsを呼び出しBean定義を登録してる …=> AbstractApplicationContext#refresh => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
  39. ίϯϙʔωϯτεΩϟϯͷྲྀΕ 68 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinitionR egistry DefaultListable BeanFactory

    ConfigurationClassP ostProcessor .classϑΝΠϧ ClassPathScanningCandidate ComponentProvider ݺͼग़͠ ୳͢ PathMatchingResourcePatternResolver を使ってclassファイルを探す File#listFilesを使って探索する
  40. ίϯϙʔωϯτεΩϟϯͷྲྀΕ 69 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinitionR egistry DefaultListable BeanFactory

    ConfigurationClassP ostProcessor .classϑΝΠϧ ClassPathScanningCandidate ComponentProvider ݺͼग़͠ ୳͢&ղੳ ClassReaderと AnnotationMetadataReadingVisitorを使っ てclassファイルのバイトコードを解析する
  41. ίϯϙʔωϯτεΩϟϯͷྲྀΕ 70 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry DefaultListable BeanFactory

    ConfigurationClass PostProcessor .classϑΝΠϧ ScannedBean Definition ClassPathScanningCandidate ComponentProvider ݺͼग़͠ ୳͢&ղੳ ੜ੒ Beanとなるクラスのみ
  42. ίϯϙʔωϯτεΩϟϯͷྲྀΕ 71 AnnotationConfig ApplicationContext Generic ApplicationContext BeanDefinition Registry DefaultListable BeanFactory

    ConfigurationClassP ostProcessor .classϑΝΠϧ ScannedBean Definition ClassPathScanningCandidate ComponentProvider ݺͼग़͠ ୳͢&ղੳ ੜ੒ 1 N BeanDefinitionReaderUtilsに よって登録される 最初のBean定義の登録と同じ
  43. 74 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ 終わり
  44. 75 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ PostProcessorRegistrationDelegateを 使ってbeanFactoryに登録する http://docs.spring.io/spring/docs/current/spring-framework- reference/htmlsingle/#beans-factory-extension-bpp
  45. 76 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ メッセージの初期化 http://docs.spring.io/spring/docs/current/spring-framework- reference/htmlsingle/#context-functionality-messagesource イベントリスナー http://docs.spring.io/spring/docs/current/spring-framework- reference/htmlsingle/#context-functionality-events
  46. 78 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ϝοηʔδͷॳظԽ΍ΠϕϯτϦεφʔͷొ࿥ͳͲ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ ここを見ていく
  47. 80 • ͬ͘͟Γͱ͜Μͳײ͡ • #FBO໊͔Β਌#FBOఆٛΛϚʔδͨ͠#FBO%FpOJUJPOΛऔಘ͢Δ IUUQEPDTTQSJOHJPTQSJOHEPDTDVSSFOUTQSJOHGSBNFXPSLSFGFSFODFIUNMTJOHMFCFBOT SFGFMFNFOU • ந৅ΫϥεͰ͸ͳ͘ɺTJOHMFUPOείʔϓͰɺ-B[Z*OJUͰ͸ͳ͍΋ͷʹ ରͯ͠HFU#FBOϝιουΛݺͿ

    IUUQEPDTTQSJOHJPTQSJOHEPDTDVSSFOUTQSJOHGSBNFXPSLSFGFSFODFIUNMTJOHMFCFBOT GBDUPSZMB[ZJOJU for (String beanName : this.beanDefinitionNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { getBean(beanName); } }
  48. • #FBOΛੜ੒͢Δͱ͜Ζʂ • είʔϓʹԠͯ͡෼ذ • ࠓճ͸TJOHMFUPOείʔϓͷ৔߹Λݟ͍ͯ͘ // Create bean instance.

    if (mbd.isSingleton()) { } else if (mbd.isPrototype()) { } else { } AbstractBeanFactory#getBean
  49. HFU#FBOͷྲྀΕ 85 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry getSingleton メソッド
  50. 87 DefaultSingletonBeanRegistry#getSingleton • TJOHMFUPOείʔϓͷ#FBOΛੜ੒ࡁΈ͔Ͳ͏͔Λௐ΂Δ • ੜ੒ࡁΈͷ৔߹͸ͦΕΛฦ͚ͩ͢ synchronized (this.singletonObjects) { Object

    singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { // Beanを生成する処理 } return (singletonObject != NULL_OBJECT ? singletonObject : null); }
  51. HFU#FBOͷྲྀΕ 88 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry getSingleton メソッド
  52. HFU#FBOͷྲྀΕ 89 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry createBean メソッド
  53. HFU#FBOͷྲྀΕ 93 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry createBean メソッド
  54. HFU#FBOͷྲྀΕ 94 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry resolveBeanClass メソッド
  55. HFU#FBOͷྲྀΕ 95 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListableB eanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry @ConfigurationのBean定義についてはClassイ ンスタンスを返すだけ コンポーネントスキャンしたBean定義について はClassインスタンスを生成する必要がある
  56. HFU#FBOͷྲྀΕ 96 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry ClassLoaderインスタンス を保持してる
  57. HFU#FBOͷྲྀΕ 97 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListableBea nFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry ClassLoaderとBeanDefinitionが 持つクラス名を引数で渡し、Class インスタンスを取得する ClassLoader#loadClass ClassUtils
  58. 99 @Component public class PrintService { public void print(String s)

    { System.out.println(s); } } @Component public class HelloWorldService { private PrintService printService; @AutoWired public HelloWorldService(PrintService printService) { this.printService = printService; } public void helloWorld() { printService.print("Hello, World!"); } }
  59. 100 AbstractAutowireCapableBeanFactory#createBean • ίϯετϥΫλҾ਺ͷ$POTUSVDUPSΠϯελϯεΛऔಘ͢Δ෦෼ • ࠓճͷαϯϓϧͩͱ)FMMP8PSME4FSWJDFͷ#FBOఆٛʹରͯ͠ɺ 1SJOU4FSWJDFΫϥεͷ$POTUSVDUPSΠϯελϯεΛऔಘ͢Δ • Ұ෦ͷ#FBO1PTU1SPDFTTPSΛ࢖༻ͯ͠औಘ͢Δ •

    4NBSU*OTUBOUJBUJPO"XBSF#FBO1PTU1SPDFTTPSΛܧঝͨ͠ #FBO1PTU1SPDFTTPS • ࠓճ͸"VUPXJSF"OOPUBUJPO#FBO1PTU1SPDFTTPS͕֘౰ Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors( beanClass, beanName);
  60. 104 Abstract BeanFactory AbstractAutowireCapable BeanFactory Constructor Resolver DefaultListable BeanFactory getBean

    PrintServiceのBeanを取得するた めにresolveDependencyメソッド を呼ぶ
  61. 107 Abstract BeanFactory AbstractAutowireCapable BeanFactory Constructor Resolver SimpleInstantiation Strategy DefaultListable

    BeanFactory BeanUtils getBean Constructor#newInstanceと PrintServiceのBeanを使って HelloWorldServiceのBeanを生成
  62. 108 Abstract BeanFactory AbstractAutowireCapable BeanFactory Constructor Resolver SimpleInstantiation Strategy DefaultListable

    BeanFactory BeanUtils getBean Constructor#newInstanceと PrintServiceのBeanを使って HelloWorldServiceのBeanを生成 コンストラクタインジェクション!
  63. HFU#FBOͷྲྀΕΛ੔ཧ 111 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry Beanの出来上がり!
  64. HFU#FBOͷྲྀΕΛ੔ཧ 112 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry 出来上がったBeanを後で使えるよう に取っておく
  65. HFU#FBOͷྲྀΕΛ੔ཧ 113 AnnotationConfig ApplicationContext Generic ApplicationContext DefaultListable BeanFactory Abstract BeanFactory

    AbstractAutowireCapable BeanFactory DefaultSingleton BeanRegistry getBeanメソッド終了!
  66. 114 AnnotationConfigApplicationContext#new => AbstractApplicationContext#refresh  ४උ͢Δ  #FBO'BDUPSZΛ४උ͢Δ  #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢

     #FBO1PTU1SPDFTTPSΛొ࿥͢Δ  ͦͷଞ΋Ζ΋Ζ  TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ  $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ 終わり
  67. 115 public AnnotationConfigApplicationContext( Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }

    AnnotationConfigApplicationContext#new • ͍ͭʹ"OOPUBUJPO$POpH"QQMJDBUJPO$POUFYUͷίϯετϥΫλ͕ऴ Θͬͨɾɾɾ
  68. @Configuration @ComponentScan public class MyApp { public static void main(String[]

    args) { ApplicationContext c = new AnnotationConfigApplicationContext(MyApp.class); HelloWorldService helloWorldService = c.getBean(HelloWorldService.class); helloWorldService.helloWorld(); } } ࠷ॳͷίʔυ 116 • "QQMJDBUJPO$POUFYU׬੒ʂ
  69. @Configuration @ComponentScan public class MyApp { public static void main(String[]

    args) { ApplicationContext c = new AnnotationConfigApplicationContext(MyApp.class); HelloWorldService helloWorldService = c.getBean(HelloWorldService.class); helloWorldService.helloWorld(); } } ࠷ॳͷίʔυ 117 • "QQMJDBUJPO$POUFYUͷHFU#FBO͸ɺ͖ͬ͞ग़͖ͯͨ "CTUSBDU#FBO'BDUPSZHFU#FBOΛݺΜͰΔ͚ͩ • ੜ੒ࡁΈͷTJOHMFUPOείʔϓͷ#FBOΛऔಘͰ͖Δ
  70. 125 // 準備 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); AnnotatedBeanDefinitionReader reader

    = new AnnotatedBeanDefinitionReader(beanFactory); // 明示的にaddBeanPostProcessorしないとAbstractBeanFactoryの // フラグ(hasInstantiationAwareBeanPostProcessors)が立たなかった beanFactory.addBeanPostProcessor( beanFactory.getBean(AutowiredAnnotationBeanPostProcessor.class)); // Bean定義の登録 reader.register(MyApp.class); // コンポーネントスキャン ConfigurationClassPostProcessor bpp = beanFactory.getBean(ConfigurationClassPostProcessor.class); bpp.setEnvironment(new StandardEnvironment()); bpp.postProcessBeanDefinitionRegistry(beanFactory); // Beanの取得 beanFactory.getBean(HelloWorldService.class).helloWorld();
  71. ;Γ͔͑ͬͯΈΔ 127 • %*ʹؔ͢ΔΞϨίϨΛ΍Δͷʹඞཁͳͷ͸ɺ#FBO'BDUPSZͱ #FBO%FpOJUJPO3FBEFSͩͬͨ • IUUQEPDTTQSJOHJPTQSJOHEPDTDVSSFOUTQSJOHGSBNFXPSLSFGFSFODFIUNMTJOHMF DPOUFYUJOUSPEVDUJPODUYWTCFBOGBDUPSZ • %FGBVMU-JTUBCMF#FBO'BDUPSZͷ࢓ࣄଟ͗͢ʂܧঝ͕ෳࡶʂ

    • ֤ΠϯλϑΣʔεͷ໾ׂΛͬ͘͟Γ೺Ѳ͢ΔͱಡΈ΍͘͢ͳΔ • ࢥͬͯͨΑΓ΋৭ʑͳػೳɺ֦ுϙΠϯτ͕ఏڙ͞Ε͍ͯͨ • ίʔυΛಡΜͩ͜ͱ͸ɺ͍͔ͭ໾ʹཱͭɾɾɾ͔΋ʂ ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ