コンテナーの実現

# 1 コンテナーの使い方
beanはSpringの中には一番コア的な存在です。すなわち、コンテナーです。まずbeanの定義を見ましょう。
```
public class MyTestBean {
     private String testStr = "testStr";
     public String getTestStr() {
         return testStr;
     }
     public void setTestStr(String testStr) {
         this.testStr = testStr;
     }
}
```
このbeanは特別なところはないです。単純にbeanをPOJOに変更するのはSpringの目的ですから。設置ファイルも見ましょう。
```
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.Springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.Springframework.org/schema/beans
http://www.Springframework.org/schema/beans/Spring-beans.xsd">
     <bean id="myTestBean" class="bean.MyTestBean"/>
</beans>
```
先の設置には、bean定義方法があります。Springのbeanには様々な属性があります。これから、テストコードを書きましょう。
```
@SuppressWarnings("deprecation")
public class BeanFactoryTest {
     @Test
     public void testSimpleLoad(){
             BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
             MyTestBean bean=(MyTestBean) bf.getBean("myTestBean");
             assertEquals("testStr",bean.getTestStr());
     }
}
```
直接にBeanFactoryをコンテナーとして使うのはよくないです。エンタプライズレベルのアプリケーションなら、ApplicationContextを使う場合が多いです。ここはただテストのためです。

# 2 機能分析
これから、テストコードの機能をよく分析します。まずは、コードには完成した機能は３つがあります。
- 設置ファイルbeanFactoryTest.xmlをリーディング。
- beanFactoryTest.xmlの設置によって、対応するクラスを探し、インスタンス化します。
- インスタンス化されたインスタンスを使います。

明白に紹介するために、図が付きます。想定の機能を完成するには、少なくとも３つのクラスが必要です。
- ConfigReaderは設置ファイルをリーディングまた確認します。
- ReflectionUtilは設置によって、反射してインスタンスを作ります。
- Appは以上の処理流れを繋ぎます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648622/989ab30a-4dd8-1397-99be-e64b78361d3e.png)

# 3 springの構成
## 3.1 パッケージの層の構成
beansパッケージ包には各ソースコードbeansの機能は以下のように。 
- src/main/javaはSpringのロジック。
- src/main/resourcesは設置ファイルを保存する場所。
- src/test/javaはテストコードを保存する場所。
- src/test/resourcesは設置ファイルを保存する場所。

## 3.2 コアクラス
Springには２つのコアクラスがあります。
1. DefaultListableBeanFactory 
XmlBeanFactoryはDefaultListableBeanFactoryを継承します。DefaultListableBeanFactoryはbeanロードのコア的な部分で、Springにはデファイアント実現です。XmlBeanFactoryははかのDefaultListableBeanFactoryと違うところはXmlBean-FactoryではXMLのXmlBeanDefinition-Readerを使っています。
![DefaultListableBeanFactory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648622/ecede573-cb35-785d-94d4-14cc2abd8a60.png)
上の図により、DefaultListableBeanFactoryの関係がわかりました。図には各クラスの機能を紹介しましょう。

- AliasRegistry：aliasのCRUDを定義します
- SimpleAliasRegistry：mapをaliasのcacheとして使って、AliasRegistryインスタンスを実現します。
- SingletonBeanRegistry：シングルパターンのインスタンスをレジスタまた獲得します。
- BeanFactory：beanまたbeanの各属性を獲得します。
- DefaultSingletonBeanRegistry：SingletonBeanRegistryインスタンスを実現します。
- HierarchicalBeanFactory：BeanFactoryを継承し、parentFactoryの機能を支えます。  
- BeanDefinitionRegistry：BeanDefinitionのCRUDを定義します。
- FactoryBeanRegistrySupport：DefaultSingletonBeanRegistryの上で、FactoryBeanの特殊処理機能を追加します。  
- ConfigurableBeanFactory：Factoryの各ファンクションを提供します。
- ListableBeanFactory：条件により、beanの設置を獲得します。
- AbstractBeanFactory：FactoryBeanRegistrySupportとConfigurableBeanFactoryの機能を総合します。  
- AutowireCapableBeanFactory：beanに関係あるファンクションを提供します。
- AbstractAutowireCapableBeanFactory：AbstractBeanFactoryを加えて、AutowireCapableBeanFactoryインスタンスを実現します。
- ConfigurableListableBeanFactory：beanの設置を獲得します。
- DefaultListableBeanFactory：以上の機能を加えて、beanをレジスタした後の処理を提供します。

2. XmlBeanDefinitionReader 
XMLファイルをリーディングｓることはSPRINGにとって重要な部分です。XmlBeanDefinitionReaderから実行流れを整理しましょう。
まずは各クラスを見ます。
- ResourceLoader：リソースをロードします。
- BeanDefinitionReader：ロードしたリソースをBeanDefinitionに変更するために定義した各機能です。
- EnvironmentCapable：Environmentを獲得する方法を定義します。
- DocumentLoader：リソースファイルのロードからDocumentに変更する方法を定義します。
- AbstractBeanDefinitionReader：EnvironmentCapableとBeanDefinitionReaderを定義したファンクションを実現します。  
- BeanDefinitionDocumentReader：Docuemntをリーディングして、BeanDefinitionを登録します。
- BeanDefinitionParserDelegate：Elementの各ファンクションを定義します。
以上の分析により、XML設置ファイルをリーディングする流れを整理しました。以下の図のように
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648622/35636639-cc55-f014-445e-1295ca83143f.png)

1. AbstractBeanDefinitionReaderを継承したファンクションにより、ResourLoaderはリソースファイルをResourceインスタンスに変更します。
2. DocumentLoaderを通じてResourceファイルからDocumentに変更します。
3. BeanDefinitionDocumentReaderインタフェースを実現したDefaultBeanDefinitionDocumentReaderクラスを通じて、Documentを解析、またBeanDefinitionParserDelegateを通じてElementを解析します。