春のブートリフレッシュ処理

免責事項:この記事はブロガーオリジナル記事ですが、許可ブロガーなく再生してはなりません。https://blog.csdn.net/yj1499945/article/details/87090676

本明細書で使用する場合、それは春ブーツ1.5.9です

具体的な方法を見てください

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

いくつかは、実際にここにほとんどの時間を開始するために全体の春ブーツのように見えます

prepareRefresh

開始時刻を設定し、いくつかの設定を初期化し、必要な設定のいくつかがあるかどうかを確認してください

prepareBeanFactory

豆の工場出荷時の設定などの属性、多くの:クラスローダ(Appclassloader)、(式はBean定義のいくつかを解決StandardBeanExpressionResolver)属性エディタレジストラ(ResourceEditorRegistrar)を追加し、BeanPostProcessorを追加表現パーサーを設定します

このような環境として、いくつかの他の情報Beanを注入し、systemPropertiesが好きです。

postProcessBeanFactory

、春のブートで使用AnnotationConfigEmbeddedWebApplicationContextある何かをするコンテキストのサブクラスをしてみましょう

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.postProcessBeanFactory(beanFactory);
        if (this.basePackages != null && this.basePackages.length > 0) {
            this.scanner.scan(this.basePackages);
        }

        if (this.annotatedClasses != null && this.annotatedClasses.length > 0) {
            this.reader.register(this.annotatedClasses);
        }

    }

行うには、サブクラスは、パッケージパスのスキャンと登録豆を下に設定することです。しかし、これはNullにデフォルト値を設定する必要があります

invokeBeanFactoryPostProcessors

文字通りの意味はBeanFactoryPostProcessorsを初期化することです。たとえば、次のようにConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessorと。

    public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
   if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
            Iterator var6 = beanFactoryPostProcessors.iterator();

            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }
}
}

上記のコードは、一部をとる処理を着信一部beanFactoryPostProcessorsに見ることができます。コアメソッドのpostProcessBeanDefinitionRegistryを呼び出して、この方法は、異なる実装クラスが同じではありませんです。実現ConfigurationClassPostProcessorこのクラスについては、ここで述べました。このクラスのpostProcessBeanDefinitionRegistryメソッドは、クラスを持つすべての@Configurationを探します。クラスは文字列のみを保存した解析され、ここでたBeanFactoryに保存されます、他の操作が行われていません。これは、ダウン操作はあまり拡大し、ここで言うことができない方法です。

優先順位の次の3つのレベルがクラスから取得されるBeanDefinitionRegistryPostProcessorのbeanfactotyとpostProcessBeanDefinitionRegistryメソッド呼び出しを実装します。優先順位は、順序、実装がないPriorityOrderedました。

次のステップは、上記ルーチンクラスがBeanFactoryPostProcessorを実装し、postProcessBeanFactoryメソッドを呼び出し得ることです。

ここでは違い、BeanDefinitionRegistryPostProcessorとBeanFactoryPostProcessorを避けます。

BeanFactoryPostProcessor

名前から判断すると、それはBeanFactory我々が最初に理解し、後処理クラスBeanFactory

BeanFactory位置は、それがさまざまで、非常に高いですBean、植物の範囲を提供getBeanする方法が一般的に使用されApplicationContext、それを継承します。

BeanFactoryPostProcessorつまり、BeanFactory後処理クラス、私たちがすることができBeanFactory、初期化した後、いくつかの操作を行います。これは、提供postProcessBeanFactory()方法、このメソッドが呼び出されたときに、すべてはBean私たちが初期化することができ、それを通して作成されているが、他の言葉で。初期化されていないが、任意のBean前に、読んで変更することさえ、さまざまな操作を行うBeanDefinition(豆のメタデータの定義を)。

BeanDefinitionRegistryPostProcessor

このインターフェースが継承するBeanFactoryPostProcessorビューの名前から、このインタフェースはBeanDefinitionRegistry、ポストプロセッサ、我々が最初に導入しますBeanDefinitionRegistry

BeanDefinitionRegistry登録するために使用されるBeanDefinition。でBeanDefinitionありBean構成やメタデータBeanなどの記述情報Bean、上記。属性値、パラメータ値および他の設定方法BeanFactoryBeanDefinition、その登録によっても。

BeanDefinitionRegistryPostProcessorそれはBeanFactoryPostProcessor許可証の延長BeanFactoryPostProcessorするために呼び出される前にBeanDefinition、特に登録することができ、何かをするBeanFactoryPostProcessorにはBeanDefinitionそれは方法を提供する。postProcessBeanDefinitionRegistry()この方法は、すべてが、呼び出されたときに、BeanDefinitionロードされているが、すべてがBean作成されていません。

注意:

  • すべてのBean世代は順序があります定义 --> 创建 --> 初始化
  • BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistryこの方法はBean定义しかし、まだされていない创建ときに実行します。
  • BeanFactoryPostProcessorpostProcessBeanFactory方法はBean创建しかし、まだされていない初始化実行時間

 

registerBeanPostProcessors

次のステップは、BeanPostProcessors登録されている。まずたBeanFactoryから順に従って実装対応するクラスBeanPostProcessorを得ることです。

PriorityOrderedさ優先、順序ではなく、実装によります。たBeanFactoryするBeanPostProcessorsの三つのカテゴリーを追加し、この添加は、優先度に応じて追加されます。

initMessageSource

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("messageSource")) {
            this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    hms.setParentMessageSource(this.getInternalParentMessageSource());
                }
            }

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        } else {
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(this.getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton("messageSource", this.messageSource);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate MessageSource with name 'messageSource': using default [" + this.messageSource + "]");
            }
        }

    }

国際通りDelegatingMessageSourceハンドリングクラスを開始しました。

initApplicationEventMulticaster

まず、我々は概念のいくつかを明確にする必要があり

イベント:ApplicationEvent

イベントリスナー:ApplicationListener、処理のためにイベントに耳を傾けます。

イベント放送局:ApplicationEventMulticaster、すべてのリスナーにブロードキャストSpringpublishイベント。

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
            }
        }

    }

このメソッドは、デフォルトの放送局としてSimpleApplicationEventMulticasterを初期化します

onRefresh

この方法は、親EmbeddedWebApplicationContext AnnotationConfigEmbeddedWebApplicationContextによって実装されます

    private void createEmbeddedServletContainer() {
        EmbeddedServletContainer localContainer = this.embeddedServletContainer;
        ServletContext localServletContext = this.getServletContext();
        if (localContainer == null && localServletContext == null) {
            EmbeddedServletContainerFactory containerFactory = this.getEmbeddedServletContainerFactory();
            this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(new ServletContextInitializer[]{this.getSelfInitializer()});
        } else if (localServletContext != null) {
            try {
                this.getSelfInitializer().onStartup(localServletContext);
            } catch (ServletException var4) {
                throw new ApplicationContextException("Cannot initialize servlet context", var4);
            }
        }

        this.initPropertySources();
    }

これはコードの一部であり、生成されるTomcatEmbeddedServletContainerの主容器。ここでは3つのコンテナの合計

UndertowEmbeddedServletContainer

JettyEmbeddedServletContainer

TomcatEmbeddedServletContainer

registerListeners

 protected void registerListeners() {
        Iterator var1 = this.getApplicationListeners().iterator();

        while(var1.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var1.next();
            this.getApplicationEventMulticaster().addApplicationListener(listener);
        }

        String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
        String[] var7 = listenerBeanNames;
        int var3 = listenerBeanNames.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            String listenerBeanName = var7[var4];
            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            Iterator var9 = earlyEventsToProcess.iterator();

            while(var9.hasNext()) {
                ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
                this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }

    }

時間リスナーのばね容器たBeanFactoryの時間リスナーはイベント放送局に追加されます

 

finishBeanFactoryInitialization

 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                public String resolveStringValue(String strVal) {
                    return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

彼らは反射により実際のオブジェクトを取得したいたBeanFactoryのみの文字列Beanオブジェクトそれ、前にそれらを覚えておいてください。preInstantiateSingletonsによって最も重要な方法は、これがデフォルトたBeanFactoryであるDefaultListableBeanFactory

 

finishRefresh

    protected void finishRefresh() {
        this.initLifecycleProcessor();
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
        LiveBeansView.registerApplicationContext(this);
    }

ここでLifecycleProcessoerクラスを達成するために更新します。

投稿ContextRefreshedEventイベントApplicationListenerは、操作の対応する応答を知らせます

registerApplicationContext JMX関連するものであり登録されています

おすすめ

転載: blog.csdn.net/yj1499945/article/details/87090676