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

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

bati11
December 03, 2016

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

bati11

December 03, 2016
Tweet

More Decks by bati11

Other Decks in Programming

Transcript

  1. 4QSJOH͸
    Ͳ͏΍ͬͯ%*͍ͯ͠Δͷ͔ʁ

    ++6($$$GBMM
    CBUJ [email protected]

    View Slide

  2. 4QSJOH$PSFͱ
    %*ίϯςφ

    View Slide

  3. ຊࢿྉͰ࢖༻͢Δ4QSJOU'SBNFXPSLͷόʔδϣϯ͸Ͱ͢
    3

    View Slide

  4. 4QSJOH$PSF5FDIOPMPHJFT
    • 4QSJOH'SBNFXPSLͷυΩϡϝϯτΛݟͯΈΔ
    • ʮᶙ$PSF5FDIOPMPHJFTʯ
    4

    View Slide

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

    • "TQFDU0SJFOUFE1SPHSBNNJOHXJUI4QSJOH
    • 4QSJOH"01"1*T
    5

    View Slide

  6. 4QSJOH$PSF5FDIOPMPHJFT
    • 5IF*P$DPOUBJOFS
    • 3FTPVSDFT
    • 7BMJEBUJPO %BUB#JOEJOH BOE5ZQF$PODFSTJPO
    • 4QSJOH&YQSFTTJPO-BOHVBHF 4Q&-

    • "TQFDU0SJFOUFE1SPHSBNNJOHXJUI4QSJOH
    • 4QSJOH"01"1*T
    6
    今日話すのはここ

    View Slide

  7. 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();
    }
    }

    View Slide

  8. @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の管理対象となるインスタンス)

    View Slide

  9. @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
    定義を探してくれる

    View Slide

  10. 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!");
    }
    }

    View Slide

  11. 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なども同じ

    View Slide

  12. 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してくれる

    View Slide

  13. 4QSJOHͷίʔυΛಡΜͰΈͨ

    View Slide

  14. 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();
    }
    }

    View Slide

  15. #FBOఆٛͷొ࿥

    View Slide

  16. @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アノ
    テーションがついてるクラスを渡す

    View Slide

  17. 17
    AnnotationConfigApplicationContext#new
    public AnnotationConfigApplicationContext(
    Class>... annotatedClasses) {
    this();
    register(annotatedClasses);
    refresh();
    }

    View Slide

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

    View Slide

  19. 19
    • ҎԼͷΠϯελϯεΛϑΟʔϧυʹอ࣋
    • "OOPUBUFE#FBO%FpOJUJPO3FBEFS
    • $MBTT1BUI#FBO%FpOJUJPO4DBOOFS
    AnnotationConfigApplicationContext#new
    public AnnotationConfigApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

    View Slide

  20. 20
    public AnnotationConfigApplicationContext(
    Class>... annotatedClasses) {
    this();
    register(annotatedClasses);
    refresh();
    }
    AnnotationConfigApplicationContext#new
    registerメソッドにClass
    を渡してる

    View Slide

  21. #FBOఆٛొ࿥ͷྲྀΕ
    21
    AnnotationConfig

    ApplicationContext
    registerメソッド

    View Slide

  22. #FBOఆٛొ࿥ͷྲྀΕ
    22
    AnnotationConfig

    ApplicationContext
    AnnotatedBean

    DefinitionReader
    registerメソッド

    View Slide

  23. 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

    View Slide

  24. 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で
    表現される

    View Slide

  25. 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

    View Slide

  26. 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

    View Slide

  27. 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を保持する

    View Slide

  28. 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

    View Slide

  29. 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
    次はここを見ていく

    View Slide

  30. 30
    AnnotationConfigApplicationContext#new => #register
    => AnnotatedBeanDefinitionReader#register
    BeanDefinitionReaderUtils.registerBeanDefinition(
    definitionHolder, this.registry);
    • #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ

    View Slide

  31. 31
    AnnotationConfigApplicationContext#new => #register
    => AnnotatedBeanDefinitionReader#register
    BeanDefinitionReaderUtils.registerBeanDefinition(
    definitionHolder, this.registry);
    • #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ
    さっき作ったMyAppクラスのBean定義
    を保持するBeanDefinitionHolder

    View Slide

  32. 32
    AnnotationConfigApplicationContext#new => #register
    => AnnotatedBeanDefinitionReader#register
    BeanDefinitionReaderUtils.registerBeanDefinition(
    definitionHolder, this.registry);
    • #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ
    this.registryって何?

    View Slide

  33. 33
    public AnnotationConfigApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    AnnotationBeanDefinitionReaderの
    this.registryに、
    AnnotationConfigApplicationContextが
    代入される

    View Slide

  34. 34
    AnnotationConfigApplicationContext#new => #register
    => AnnotatedBeanDefinitionReader#register
    BeanDefinitionReaderUtils.registerBeanDefinition(
    definitionHolder, this.registry);
    • #FBO%FpOJUJPO3FBEFS6UJMTSFHJTUFS#FBO%FpOJUJPOʹॲཧΛҕৡ͢Δ
    this.registryは
    AnnotationConfigApplicationContext

    View Slide

  35. #FBOఆٛొ࿥ͷྲྀΕ
    35
    AnnotationConfig

    ApplicationContext
    AnnotatedBean

    DefinitionReader
    registerメソッド

    View Slide

  36. #FBOఆٛొ࿥ͷྲྀΕ
    36
    AnnotationConfig

    ApplicationContext
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    Bean定義を表現するクラス

    View Slide

  37. #FBOఆٛొ࿥ͷྲྀΕ
    37
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    AnnotationConfigApplicationContextは
    BeanDefinitionRegistryのサブクラス

    View Slide

  38. #FBOఆٛొ࿥ͷྲྀΕ
    38
    AnnotationConfig

    ApplicationContext
    GenericApplication
    Context
    BeanDefinition

    Registry
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    BeanDefinition

    ReaderUtils
    registerBeanDefinitionメソッド
    beanDefinitionHolderとregistryが引数

    View Slide

  39. 39
    …=> AnnotatedBeanDefinitionReader#register => #registerBean

    => BeanDefinitionReaderUtils#registerBeanDefinition
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName,
    definitionHolder.getBeanDefinition());
    registryにBeanの名前と
    Bean定義を登録する

    View Slide

  40. ͭ·Γ
    40
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    1
    N
    BeanDefinitionReaderUtils
    経由で登録される
    BeanDefinitionR
    eaderUtils

    View Slide

  41. ͭ·Γ
    41
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    1
    N
    登録処理は
    registerBeanDefinitionメソッド
    BeanDefinitionR
    eaderUtils

    View Slide

  42. 42
    this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
    …=> BeanDefinitionReaderUtils#registerBeanDefinition

    => GenericApplicationContext#registerBeanDefinition
    this.beanFactoryは、
    DefaultListableBeanFactoryインスタンスで
    初期化されている

    View Slide

  43. %FGBVMU-JTUBCMF#FBO'BDUPSZ

    View Slide

  44. %FGBVMU-JTUBCMF#FBO'BDUPSZͷܧঝ
    44

    View Slide

  45. %FGBVMU-JTUBCMF#FBO'BDUPSZͷܧঝ
    45

    View Slide

  46. ͭ·Γ
    46
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    1
    N
    BeanDefinitionR
    eaderUtils
    登録するのは
    registerBeanDefinitionメソッド

    View Slide

  47. ͭ·Γ
    47
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    1
    N
    DefaultListable

    BeanFactory
    registerBeanDefinitionメソッドに
    委譲
    BeanDefinitionR
    eaderUtils

    View Slide

  48. ͭ·Γ
    48
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    AnnotatedBean

    DefinitionReader
    AnnotatedGeneric
    BeanDefinition

    1
    N
    DefaultListable

    BeanFactory
    BeanDefinitionはインスタンス変数の
    ConcurrentHashMapに保存される
    BeanDefinitionR
    eaderUtils

    View Slide

  49. public AnnotationConfigApplicationContext(
    Class>... annotatedClasses) {
    this();
    register(annotatedClasses);
    refresh();
    }
    ͜͜·ͰΛ੔ཧ
    49
    • ͕͜͜ऴΘͬͨ
    • .Z"QQΫϥεͷ#FBOఆٛΛొ࿥ͨ͠

    View Slide

  50. ͜͜·ͰΛ੔ཧ
    50
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    AnnotatedBean

    DefinitionReader
    DefaultListable

    BeanFactory
    BeanDefinition

    ReaderUtils
    Class
    BeanDefinition
    Holder
    BeanDefinition
    Concurrent
    HashMap
    BeanDefinition
    BeanDefinition

    View Slide

  51. ࣍͸ίϯϙʔωϯτεΩϟϯ

    View Slide

  52. 52
    public AnnotationConfigApplicationContext(
    Class>... annotatedClasses) {
    this();
    register(annotatedClasses);
    refresh();
    }
    AnnotationConfigApplicationContext#new
    • ࣍͸ͬͪ͜
    • SFGSFTIϝιου͸਌ΫϥεͰ͋Δ"CTUSBDU"QQMJDBUJPO$POUFYUͰ࣮
    ૷͞Ε͍ͯΔ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  56. %FGBVMU-JTUBCMF#FBO'BDUPSZͷܧঝ
    56

    View Slide

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

    View Slide

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

    View Slide

  59. 59
    …=> AbstractApplicationContext#refresh
    => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
    J #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛ࣮૷ͨ͠Ϋϥεͷ
    QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZΛ࣮ߦ
    JJ #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛ࣮૷ͨ͠Ϋϥεͷ
    QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ
    JJJ #FBO'BDUPSZ1PTU1SPDFTTPSΛ࣮૷ͨ͠Ϋϥεͷ
    QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ

    View Slide

  60. 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

    View Slide

  61. 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

    View Slide

  62. 62
    J #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛܧঝͨ͠Ϋϥεͷ
    QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZΛ࣮ߦ
    JJ #FBO%FpOJUJPO3FHJTUSZ1PTU1SPDFTTPSΛܧঝͨ͠Ϋϥεͷ
    QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ
    JJJ #FBO'BDUPSZ1PTU1SPDFTTPSΛܧঝͨ͠Ϋϥεͷ
    QPTU1SPDFTT#FBO'BDUPSZΛ࣮ߦ
    自前のBeanFactoryPostProcessor
    今回は定義していない
    …=> AbstractApplicationContext#refresh
    => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

    View Slide

  63. 63
    ͭ·Γࠓճͷέʔεͩͱ$POpHVSBUJPO$MBTT1PTU1SPDFTTPSͷ
    ᶃ QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZ
    ᶄ QPTU1SPDFTT#FBO'BDUPSZ
    ͕࣮ߦ͞ΕΔɻ
    …=> AbstractApplicationContext#refresh
    => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

    View Slide

  64. 64
    ͭ·Γࠓճͷέʔεͩͱ$POpHVSBUJPO$MBTT1PTU1SPDFTTPSͷ
    ᶃ QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZ
    ᶄ QPTU1SPDFTT#FBO'BDUPSZ
    ͕࣮ߦ͞ΕΔɻコンポーネントスキャンしてBean定義
    を登録する
    …=> AbstractApplicationContext#refresh
    => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

    View Slide

  65. ίϯϙʔωϯτεΩϟϯͷྲྀΕ
    65
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    DefaultListable

    BeanFactory

    View Slide

  66. ίϯϙʔωϯτεΩϟϯͷྲྀΕ
    66
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    DefaultListable

    BeanFactory
    ConfigurationClass

    PostProcessor
    BeanFactoryPostProcessor
    として呼び出される

    View Slide

  67. ίϯϙʔωϯτεΩϟϯͷྲྀΕ
    67
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    DefaultListable

    BeanFactory
    ConfigurationClass

    PostProcessor
    ClassPathScanningCandidate
    ComponentProvider
    ݺͼग़͠

    View Slide

  68. ίϯϙʔωϯτεΩϟϯͷྲྀΕ
    68
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinitionR
    egistry
    DefaultListable

    BeanFactory
    ConfigurationClassP
    ostProcessor
    .classϑΝΠϧ
    ClassPathScanningCandidate
    ComponentProvider
    ݺͼग़͠
    ୳͢
    PathMatchingResourcePatternResolver
    を使ってclassファイルを探す
    File#listFilesを使って探索する

    View Slide

  69. ίϯϙʔωϯτεΩϟϯͷྲྀΕ
    69
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinitionR
    egistry
    DefaultListable

    BeanFactory
    ConfigurationClassP
    ostProcessor
    .classϑΝΠϧ
    ClassPathScanningCandidate
    ComponentProvider
    ݺͼग़͠
    ୳͢&ղੳ
    ClassReaderと
    AnnotationMetadataReadingVisitorを使っ
    てclassファイルのバイトコードを解析する

    View Slide

  70. ίϯϙʔωϯτεΩϟϯͷྲྀΕ
    70
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    DefaultListable

    BeanFactory
    ConfigurationClass

    PostProcessor
    .classϑΝΠϧ
    ScannedBean
    Definition
    ClassPathScanningCandidate
    ComponentProvider
    ݺͼग़͠
    ୳͢&ղੳ
    ੜ੒
    Beanとなるクラスのみ

    View Slide

  71. ίϯϙʔωϯτεΩϟϯͷྲྀΕ
    71
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    BeanDefinition

    Registry
    DefaultListable

    BeanFactory
    ConfigurationClassP
    ostProcessor
    .classϑΝΠϧ
    ScannedBean
    Definition
    ClassPathScanningCandidate
    ComponentProvider
    ݺͼग़͠
    ୳͢&ղੳ
    ੜ੒
    1 N
    BeanDefinitionReaderUtilsに
    よって登録される
    最初のBean定義の登録と同じ

    View Slide

  72. 72
    ͭ·Γࠓճͷέʔεͩͱ$POpHVSBUJPO$MBTT1PTU1SPDFTTPSͷ
    ᶃ QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZ
    ᶄ QPTU1SPDFTT#FBO'BDUPSZ
    ͕࣮ߦ͞ΕΔɻコンポーネントスキャンが終わった
    …=> AbstractApplicationContext#refresh
    => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

    View Slide

  73. 73
    ͭ·Γࠓճͷέʔεͩͱ$POpHVSBUJPO$MBTT1PTU1SPDFTTPSͷ
    ᶃ QPTU1SPDFTT#FBO%FpOJUJPO3FHJTUSZ
    ᶄ QPTU1SPDFTT#FBO'BDUPSZ
    ͕࣮ߦ͞ΕΔɻ
    ConfigurationClassEnhancer#enhance
    でMyAppをCGLIBのサブクラス化
    AOPでプロキシ化する時にCGLIBを使う
    …=> AbstractApplicationContext#refresh
    => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

    View Slide

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

    View Slide

  75. 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

    View Slide

  76. 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

    View Slide

  77. ࣍͸#FBOΛੜ੒

    View Slide

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

    View Slide

  79. 79
    AnnotationConfigApplicationContext#new
    => AbstractApplicationContext#refresh
    • TJOHMFUPOείʔϓͷ#FBOΛੜ੒
    finishBeanFactoryInitialization(beanFactory);
    beanFactory.preInstantiateSingletons();
    beanFactoryはDefaultListableBeanFactory

    View Slide

  80. 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);
    }
    }

    View Slide

  81. "CTUSBDU#FBO'BDUPSZ
    HFU#FBO

    View Slide

  82. • #FBOఆٛͷEFQFOETPOଐੑΛղܾ
    IUUQEPDTTQSJOHJPTQSJOHEPDTDVSSFOUTQSJOHGSBNFXPSLSFGFSFODFIUNMTJOHMFCFBOT
    GBDUPSZEFQFOETPO
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
    AbstractBeanFactory#getBean

    View Slide

  83. • #FBOΛੜ੒͢Δͱ͜Ζʂ
    • είʔϓʹԠͯ͡෼ذ
    • ࠓճ͸TJOHMFUPOείʔϓͷ৔߹Λݟ͍ͯ͘
    // Create bean instance.
    if (mbd.isSingleton()) {
    }
    else if (mbd.isPrototype()) {
    }
    else {
    }
    AbstractBeanFactory#getBean

    View Slide

  84. HFU#FBOͷྲྀΕ
    84
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    getBeanメソッド

    View Slide

  85. HFU#FBOͷྲྀΕ
    85
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    getSingleton
    メソッド

    View Slide

  86. %FGBVMU-JTUBCMF#FBO'BDUPSZͷܧঝ
    86

    View Slide

  87. 87
    DefaultSingletonBeanRegistry#getSingleton
    • TJOHMFUPOείʔϓͷ#FBOΛੜ੒ࡁΈ͔Ͳ͏͔Λௐ΂Δ
    • ੜ੒ࡁΈͷ৔߹͸ͦΕΛฦ͚ͩ͢
    synchronized (this.singletonObjects) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null) {
    // Beanを生成する処理
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }

    View Slide

  88. HFU#FBOͷྲྀΕ
    88
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    getSingleton
    メソッド

    View Slide

  89. HFU#FBOͷྲྀΕ
    89
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    createBean
    メソッド

    View Slide

  90. %FGBVMU-JTUBCMF#FBO'BDUPSZͷܧঝ
    90

    View Slide

  91. 91
    AbstractAutowireCapableBeanFactory#createBean
    J #FBO%FpOJUJPOͱ#FBO໊͔Β#FBOͷ$MBTTΠϯελϯεΛऔಘ
    JJ $MBTTΠϯελϯε͔Β#FBOΛੜ੒
    • ίϯετϥΫλΠϯδΣΫγϣϯ
    JJJ ੜ੒ͨ͠#FBOʹରͯ͠ɺϑΟʔϧυɾηολʔΠϯδΣΫγϣϯ
    JW ੜ੒ͨ͠#FBOʹରͯ͠ɺ#FBO1PTU1SPDFTTPSͱJOJUNFUIPEͷॲཧ

    View Slide

  92. 92
    AbstractAutowireCapableBeanFactory#createBean
    J #FBO%FpOJUJPOͱ#FBO໊͔Β#FBOͷ$MBTTΠϯελϯεΛऔಘ
    JJ $MBTTΠϯελϯε͔Β#FBOΛੜ੒
    • ίϯετϥΫλΠϯδΣΫγϣϯ
    JJJ ੜ੒ͨ͠#FBOʹରͯ͠ɺϑΟʔϧυɾηολʔΠϯδΣΫγϣϯ
    JW ੜ੒ͨ͠#FBOʹରͯ͠ɺ#FBO1PTU1SPDFTTPSͱJOJUNFUIPEͷॲཧ

    View Slide

  93. HFU#FBOͷྲྀΕ
    93
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    createBean
    メソッド

    View Slide

  94. HFU#FBOͷྲྀΕ
    94
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    resolveBeanClass
    メソッド

    View Slide

  95. HFU#FBOͷྲྀΕ
    95
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListableB
    eanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    @ConfigurationのBean定義についてはClassイ
    ンスタンスを返すだけ
    コンポーネントスキャンしたBean定義について
    はClassインスタンスを生成する必要がある

    View Slide

  96. HFU#FBOͷྲྀΕ
    96
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    ClassLoaderインスタンス
    を保持してる

    View Slide

  97. HFU#FBOͷྲྀΕ
    97
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListableBea
    nFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    ClassLoaderとBeanDefinitionが
    持つクラス名を引数で渡し、Class
    インスタンスを取得する
    ClassLoader#loadClass
    ClassUtils

    View Slide

  98. 98
    AbstractAutowireCapableBeanFactory#createBean
    J #FBO%FpOJUJPOͱ#FBO໊͔Β#FBOͷ$MBTTΠϯελϯεΛऔಘ
    JJ $MBTTΠϯελϯε͔Β#FBOΛੜ੒
    • ίϯετϥΫλΠϯδΣΫγϣϯ
    JJJ ੜ੒ͨ͠#FBOʹରͯ͠ɺϑΟʔϧυɾηολʔΠϯδΣΫγϣϯ
    JW ੜ੒ͨ͠#FBOʹରͯ͠ɺ#FBO1PTU1SPDFTTPSͱJOJUNFUIPEͷॲཧ

    View Slide

  99. 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!");
    }
    }

    View Slide

  100. 100
    AbstractAutowireCapableBeanFactory#createBean
    • ίϯετϥΫλҾ਺ͷ$POTUSVDUPSΠϯελϯεΛऔಘ͢Δ෦෼
    • ࠓճͷαϯϓϧͩͱ)FMMP8PSME4FSWJDFͷ#FBOఆٛʹରͯ͠ɺ
    1SJOU4FSWJDFΫϥεͷ$POTUSVDUPSΠϯελϯεΛऔಘ͢Δ
    • Ұ෦ͷ#FBO1PTU1SPDFTTPSΛ࢖༻ͯ͠औಘ͢Δ
    • 4NBSU*OTUBOUJBUJPO"XBSF#FBO1PTU1SPDFTTPSΛܧঝͨ͠
    #FBO1PTU1SPDFTTPS
    • ࠓճ͸"VUPXJSF"OOPUBUJPO#FBO1PTU1SPDFTTPS͕֘౰
    Constructor>[] ctors =
    determineConstructorsFromBeanPostProcessors(
    beanClass, beanName);

    View Slide

  101. 101
    AbstractAutowireCapableBeanFactory#createBean
    • #FBO%FpOJUJPOͱऔಘͨ͠$POTUSVDUPSΠϯελϯεΛ࢖ͬͯίϯε
    τϥΫλΠϯδΣΫγϣϯ͢Δ෦෼
    • ࠓճͷαϯϓϧͩͱɺҎԼΛ࢖ͬͯίϯετϥΫλΠϯδΣΫγϣ
    ϯ͢Δ
    • )FMMP8PSME4FSWJDFͷ#FBO%FpOJUJPO
    • 1SJOU4FSWJDFͷ$POTUSVDUPSΠϯελϯε
    new ConstructorResolver(this)
    .autowireConstructor(beanName, mbd, ctors, explicitArgs);

    View Slide

  102. 102
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    Constructor

    Resolver
    getBean ここがBean生成のスタート
    HelloWorldServiceのBeanを
    生成しようとしてる

    View Slide

  103. 103
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    Constructor

    Resolver
    getBean
    HelloWorldServiceにPrintService
    をコンストラクタインジェクショ
    ンをしようとしてるとこ

    View Slide

  104. 104
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    Constructor

    Resolver
    DefaultListable

    BeanFactory
    getBean
    PrintServiceのBeanを取得するた
    めにresolveDependencyメソッド
    を呼ぶ

    View Slide

  105. 105
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    Constructor

    Resolver
    DefaultListable

    BeanFactory
    getBean
    Bean生成のため再帰的に
    getBeanを呼ぶことになる

    View Slide

  106. 106
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    Constructor

    Resolver
    DefaultListable

    BeanFactory
    getBean
    PrintServiceのBeanが
    返ってくる

    View Slide

  107. 107
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    Constructor

    Resolver
    SimpleInstantiation

    Strategy
    DefaultListable

    BeanFactory
    BeanUtils
    getBean
    Constructor#newInstanceと
    PrintServiceのBeanを使って
    HelloWorldServiceのBeanを生成

    View Slide

  108. 108
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    Constructor

    Resolver
    SimpleInstantiation

    Strategy
    DefaultListable

    BeanFactory
    BeanUtils
    getBean
    Constructor#newInstanceと
    PrintServiceのBeanを使って
    HelloWorldServiceのBeanを生成
    コンストラクタインジェクション!

    View Slide

  109. 109
    AbstractAutowireCapableBeanFactory#createBean
    J #FBO%FpOJUJPOͱ#FBO໊͔Β#FBOͷ$MBTTΠϯελϯεΛऔಘ
    JJ $MBTTΠϯελϯε͔Β#FBOΛੜ੒
    • ίϯετϥΫλΠϯδΣΫγϣϯ
    JJJ ੜ੒ͨ͠#FBOʹରͯ͠ɺϑΟʔϧυɾηολʔΠϯδΣΫγϣϯ
    JW ੜ੒ͨ͠#FBOʹରͯ͠ɺ#FBO1PTU1SPDFTTPSͱJOJUNFUIPEͷॲཧ
    populateBeanメソッド
    内で実施してる
    initializeBeanメソッド
    内で実施してる

    View Slide

  110. HFU#FBOͷྲྀΕΛ੔ཧ
    110
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    createBean

    View Slide

  111. HFU#FBOͷྲྀΕΛ੔ཧ
    111
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    Beanの出来上がり!

    View Slide

  112. HFU#FBOͷྲྀΕΛ੔ཧ
    112
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    出来上がったBeanを後で使えるよう
    に取っておく

    View Slide

  113. HFU#FBOͷྲྀΕΛ੔ཧ
    113
    AnnotationConfig

    ApplicationContext
    Generic

    ApplicationContext
    DefaultListable

    BeanFactory
    Abstract

    BeanFactory
    AbstractAutowireCapable
    BeanFactory
    DefaultSingleton

    BeanRegistry
    getBeanメソッド終了!

    View Slide

  114. 114
    AnnotationConfigApplicationContext#new
    => AbstractApplicationContext#refresh
    ४උ͢Δ
    #FBO'BDUPSZΛ४උ͢Δ
    #FBO'BDUPSZ1PTU1SPDFTTPSΛݺͼग़͢
    #FBO1PTU1SPDFTTPSΛొ࿥͢Δ
    ͦͷଞ΋Ζ΋Ζ
    TJOHMFUPOείʔϓͷ#FBOΛੜ੒͢Δ
    $POUFYU3FGSFTIFE&WFOUͷൃߦͳͲ
    終わり

    View Slide

  115. 115
    public AnnotationConfigApplicationContext(
    Class>... annotatedClasses) {
    this();
    register(annotatedClasses);
    refresh();
    }
    AnnotationConfigApplicationContext#new
    • ͍ͭʹ"OOPUBUJPO$POpH"QQMJDBUJPO$POUFYUͷίϯετϥΫλ͕ऴ
    Θͬͨɾɾɾ

    View Slide

  116. @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׬੒ʂ

    View Slide

  117. @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ΛऔಘͰ͖Δ

    View Slide

  118. ;Γ͔͑ͬͯΈΔ

    View Slide

  119. • ;Γ͔͑ͬͯΈΔ
    • #FBOఆٛͷొ࿥
    • ίϯϙʔωϯτεΩϟϯ
    • #FBOੜ੒ʢίϯετϥΫλΠϯδΣΫγϣϯʣ
    119

    View Slide

  120. • #FBOఆٛͷొ࿥
    • "OOPUBUFE#FBO%FpOJUJPO3FBEFSͷίϯετϥΫλͰϑϨʔϜ
    ϫʔΫͰ࢖͏#FBOఆ͕ٛొ࿥͞ΕΔ
    • "OOPUBUFE#FBO%FpOJUJPO3FBEFSͰ!$POpHVSBUJPO͕͍ͭͯ
    ΔΫϥεͷ#FBOఆٛΛ#FBO%FpOJUJPOʹม׵͢Δ
    • #FBO%FpOJUJPO͕࠷ऴతʹอଘ͞ΕΔ৔ॴ͸ɺ
    %FGBVMU-JTUBCMF#FBO'BDUPSZͷΠϯελϯεม਺
    120

    View Slide

  121. • ίϯϙʔωϯτεΩϟϯ
    • $POpHVSBUJPO$MBTT1PTU1SPDFTTPSQPTU1SPDFTT#FBO%FpOJ
    UJPO3FHJTUSZ͔Β࢝·Δ
    • ʢ"OOPUBUFE#FBO%FpOJUJPO3FBEFSͷίϯετϥΫλͰ#FBO
    ొ࿥͞ΕͯΔʣ
    121

    View Slide

  122. • #FBOੜ੒ʢίϯετϥΫλΠϯδΣΫγϣϯʣ
    • "CTUSBDU#FBO'BDUPSZHFU#FBO͔Β࢝·Δ
    • "VUPXJSFE"OOPUBUJPO#FBO1PTU1SPDFTTPSͰίϯετϥΫλ
    ΠϯδΣΫγϣϯͷҾ਺Λղܾ
    • ʢ"OOPUBUFE#FBO%FpOJUJPO3FBEFSͷίϯετϥΫλͰ#FBO
    ొ࿥͞ΕͯΔʣ
    122

    View Slide

  123. • #FBO%FpOJUJPO3FBEFS
    • #FBO%FpOJUJPOΛੜ੒
    • $POpHVSBUJPO$MBTT1PTU1SPDFTTPSΛొ࿥
    • "VUPXJSFE"OOPUBUJPO#FBO1PTU1SPDFTTPSΛొ࿥
    • %FGBVMU-JTUBCMF'BDUPSZ
    • #FBO%FpOJUJPOΛอ࣋
    • #FBOੜ੒
    123

    View Slide

  124. • ͋Εʁ
    • #FBO%FpOJUJPO3FBEFSͱ%FGBVMU-JTUBCMF#FBO'BDUPSZ͑͋͞Ε
    ͹ಈ͘Μ͡Όͳ͍ʁ
    • ʢ"QQMJDBUJPO$POUFYU͍Βͳ͘ͳ͍ʁʣ
    • ࣮ࡍɺࢼͯ͠ΈͨΒಈ͍ͨ
    124

    View Slide

  125. 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();

    View Slide

  126. ;Γ͔͑ͬͯΈΔ
    126
    • %*ʹؔ͢ΔΞϨίϨΛ΍Δͷʹඞཁͳͷ͸ɺ#FBO'BDUPSZͱ
    #FBO%FpOJUJPO3FBEFSͩͬͨ
    • IUUQEPDTTQSJOHJPTQSJOHEPDTDVSSFOUTQSJOHGSBNFXPSLSFGFSFODFIUNMTJOHMF
    DPOUFYUJOUSPEVDUJPODUYWTCFBOGBDUPSZ
    • %FGBVMU-JTUBCMF#FBO'BDUPSZͷ࢓ࣄଟ͗͢ʂܧঝ͕ෳࡶʂ
    • ֤ΠϯλϑΣʔεͷ໾ׂΛͬ͘͟Γ೺Ѳ͢ΔͱಡΈ΍͘͢ͳΔ
    • ࢥͬͯͨΑΓ΋৭ʑͳػೳɺ֦ுϙΠϯτ͕ఏڙ͞Ε͍ͯͨ
    • ίʔυΛಡΜͩ͜ͱ͸ɺ͍͔ͭ໾ʹཱͭɾɾɾ͔΋ʂ

    View Slide

  127. ;Γ͔͑ͬͯΈΔ
    127
    • %*ʹؔ͢ΔΞϨίϨΛ΍Δͷʹඞཁͳͷ͸ɺ#FBO'BDUPSZͱ
    #FBO%FpOJUJPO3FBEFSͩͬͨ
    • IUUQEPDTTQSJOHJPTQSJOHEPDTDVSSFOUTQSJOHGSBNFXPSLSFGFSFODFIUNMTJOHMF
    DPOUFYUJOUSPEVDUJPODUYWTCFBOGBDUPSZ
    • %FGBVMU-JTUBCMF#FBO'BDUPSZͷ࢓ࣄଟ͗͢ʂܧঝ͕ෳࡶʂ
    • ֤ΠϯλϑΣʔεͷ໾ׂΛͬ͘͟Γ೺Ѳ͢ΔͱಡΈ΍͘͢ͳΔ
    • ࢥͬͯͨΑΓ΋৭ʑͳػೳɺ֦ுϙΠϯτ͕ఏڙ͞Ε͍ͯͨ
    • ίʔυΛಡΜͩ͜ͱ͸ɺ͍͔ͭ໾ʹཱͭɾɾɾ͔΋ʂ
    ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ

    View Slide