springソースコード学習ノート-初期化(四)-PostProcessor


自動回転http://www.sandzhang.com/blog/2011/04/05/spring-study-notes-initialization-4/
refresh()メソッドは前編でpostProcessBenFactoryを見ました。この記事は続けて読みます。
注:refresh()のコードは再度列挙しません。springのソースコードの中でAbstractAplicationControtext類を見てください。
一、invokeBenFactoryPostProcessorsは、この方法は名前からBenFactory Processorを呼び出していることが分かります。コードも長いので、いくつかの部分に分けてみます。
第1部:
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
    List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
            new LinkedList<BeanDefinitionRegistryPostProcessor>();
    for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryPostProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
            registryPostProcessors.add(registryPostProcessor);
        }
        else {
            regularPostProcessors.add(postProcessor);
        }
    }
    Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
            beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
    List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
            new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
    OrderComparator.sort(registryPostProcessorBeans);
    for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
    invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    processedBeans.addAll(beanMap.keySet());
}
else {
    invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}
  • はまずHashSet変数processedBensを作成し、続いて判断します。beanFactoryタイプがBenDefinitionRegistryインターフェースを実現すれば、BeanFactoryオブジェクトはBenDefinitionRegistryタイプ変数registryであり、LinkdList変数reglast Postorssを作成して、一般的なProcessorstorsストアに使用します。registryPostProcessorsは、bean定義の登録情報を処理するためのPostProcessorを格納するために使用されます。
  • -7行の循環すべてのaplicationControtextに登録されているBeanFactoryPostProcessorは、BeanDefinitionRegistryPostProcessorのタイプを実現したら、対応するpostProcession DefinitionRegistry()方法を呼び出して対応する処理を行い、registryPostorss Postorssに追加します。
  • 18-25行は、まずBenFactoryのgetBensOfType(Class<T>type、bootlean include NonSingletons、bootlean allowEage Init)を呼び出して、すべてのタイプを取得してBenDefinitionPostractionsのbeanに並べ替えて、ListオブジェクトBeatringstrancionsに並べ替えてください。方法注:getBensOfType()の後にはbeanFactoryに関する専門的な研究があります。ここでは簡単に並べ替えを行います。springの内部ではOrderedインターフェースが主に実現されています。順序付けが必要なオブジェクトはこのインターフェースのgetOrder()方法を実現し、並べ替えを行う時にこの結果を比較して並べ替えを行います。また、あるオブジェクトがPriorityOrderedインターフェースである場合は優先的に並べ替えられ、同じ場合はgetOrder()の結果を比較します。
  • 26-28行は、3つのListオブジェクトに対して、invokeBenFactoryPostProcessors()方法を順次呼び出し、BenFactory PostProcessorの処理を行い、順次、registryPostProcessorsors、registryPostProcess、reglarPostProcessors。invokeBenFactory PostProcessors()メソッドのコードは簡単で、forループは各postProcessorオブジェクトのpostProcess BenFactoryメソッドを呼び出します。
  • 29行は、すべてのbeanにロードされたBeanDefinitionRegistryPostProcessorタイプのbeanの名前をprocessedBensに追加します。
  • は上記の最初の判断に戻ります。beanFactoryタイプがBenDefinitionRegistryインターフェースを実現していない場合、直接invokeBenFactory PostProcessors()メソッドを呼び出して、すべてのApple Controxtに登録されているBenFactory PostProcessorsorを処理します。
  • 第2部:
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        }
        else if (isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
    OrderComparator.sort(priorityOrderedPostProcessors);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
     
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    OrderComparator.sort(orderedPostProcessors);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
     
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  • 第1、2行目は、まず、BenFactoryPostProcessorのbeanのすべてのタイプのnameセットを取得し、変数postProcessoorNames
  • に置く。
  • 第3行は、優先処理が必要なpostProcessor
  • を格納するためにArayList変数prortyOrderedPostProcessorsを確立する。
  • 第4、5行は、それぞれ2つのArayList変数order PostProcessors Names、nonOrderedPostProcessors Namesを確立し、並べ替えられたものと並べ替えられていないものを格納するために使用される。
  • 第6-19行ループ上で取得したすべてのpostProcessorのnameセットは、条件によって異なる処理を行う。    nameが既にprocessedBensに存在しているなら、代表はすでに処理済みで、この一つをスキップします。    isTypeMatchを呼び出す方法は、beanのnameによって、PriorityOrderedインターフェースが実現されたかどうかを判断します。(上に述べた順序付けの中で、これは優先順位です。)。そうであれば、nameによって対応するbeanオブジェクトを取り出してprortyOrderedPostProcessセットに参加します。    isTypeMatchを呼び出す方法は、beanのnameに基づいて、このbeanがOrderedインターフェースを実現しているかどうかを判断します。(上に述べたように、このインターフェースを実現すれば、並べ替えができます。)。もしそうであれば、orded PostProcessorsorNamesのセットにnameを追加します。    上の条件が全部成立しないなら、nonOrderedPostProcessors Namesの集合に参加します。注:isType Match()方法については、簡単に言えば、beanのnameからbeanのオブジェクトを取り出してタイプを判断していますが、実際にはこの方法は簡単ではありません。最終的には、AbstractBenFactoryにマークを付けて、後で単独で抽出して分析してみます。
  • 第20行prortyOrderedPostProcessorsを並べ替える
  • 第21行は、invokeBenFactory PostProcessors()方法を呼び出し、prortyOrderedPostProcessorsのすべてのpostProcessorを処理する
  • を実行する。
  • 第23-28行は、getBean()法により、すべてのorded PostProcessors Namesのセットの中のpostProcessorのbeanオブジェクトを取得し、新しいセット変数ordentPostProcessorsに追加し、このセットをソートし、最後にinvokeBenFactoryPostorssorsを呼び出す(方法処理
  • )。
  • の後の部分は、並べ替えなしのnonOrderedPostProcessors Namesを処理し、並べ替えステップを除去する以外に上記のステップと同様に、
  • を繰り返し説明しない。
    二、私達はrefresh()方法に戻って、次の行を見ます。register BeanPostProcessors(beanFactory)、この方法は主にBenPostProcessorの登録に対して、いくつかの部分に分けて見ます。
    第1部:
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
  • 第1行は、ビーンPostProcessorタイプのビーンのname配列
  • をすべて取得する。
  • 行目は、ビーンPostProcessorの数を計算します。bankFactoryに登録されているビーンPostProcessorの数+1+上で取得した全てのbeanの中のビーンPostProcessorの数を計算します。この中のあの+1は、次の行のBenPostProcessors Checker
  • です。
  • 第3行はビーンPostProcessors CheckerからbeanFactoryに登録されています。このBenPostProcessorは、ビーンが作成された後、すべてのBenPostProcessorに処理されないときに、1行のinfoレベルログ
  • を印刷します。
    第2部:
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    for (String ppName : postProcessorNames) {
        if (isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
  • この部分のコードはBenFactoryPostProcessorの処理の部分と似ています。すべてのBeanPostProcessorを区別して、異なるセットに入れて、優先的に並べ替えて、並べ替えないものです。特別なところはインターナールPostProcessorsの集合が多くなり、優先順位の中のタイプはMergedBenDefinitionPostProcessorのBenPostProcessorを保存するために使われています。その主な役割はspringの運行時にBEanの定義を統合して処理するので、例えば注釈の中のbeanの定義、この部分もまだ完全にはっきりさせていないで、マークをして、後ほど特定項目の分析を帰ります。
  • 第3部:
    OrderComparator.sort(priorityOrderedPostProcessors);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
     
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    OrderComparator.sort(orderedPostProcessors);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);
     
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
     
    OrderComparator.sort(internalPostProcessors);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
     
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
  • 第1行目はprortyOrderedPostProcessorsを並べ替えて、register BenPostProcessors()方法を呼び出して登録処理します。この方法は内部コードが簡単です。つまり、このセットを循環してBeanFactory.addBenPostProcessorを呼び出して、BenPostProcessorsorごとにBeanPostProcessorをFactorerに登録します。
  • 第3-13行も前と同様に、すべてのorded PostProcessonamensのBenPostProcessorを取り出してセットに入れます。その中でMergdBenDefinitionPostProcessorタイプは依然としてinternal PostProcessorsorsに加入しています。最後の2行は先に並べ替えて、レジスターBeanPostProcessors()方法を呼び出して登録処理を行います。
  • 第14-23行はnonOrderedPostProcessors Namesに対する処理であり、上述の順序付けプロセスを除いたものに比べて、他のものは依然として続いている。
  • は、internal PostProcessorsの順序付け、登録処理に続いている。
  • 最後の行にBenPostProcessor:Apple ListenerDetectorを登録しました。これはAbstract Appliation Controtextの内部クラスです。MergedBenDefinitionPostProcessorインターフェースを実現しました。この種類はApplistener関連の東を処理しているだけです。具体的な役割はまだ分かりません。