春のクラウドプロジェクトSpringApplicationランは二回の復号を実行します

ApplicationContextInitializerはじめに

役割ConfigurableApplicationContextのタイプはApplicationContextrefresh操作の前に、私たちができるようにConfiurableApplicationContext強調処理を展開します。

ビジネスシーン

実際の開発プロセスでは、Webアプリケーションは、プログラム、アプリケーション・コンテキストの初期化を行う必要があります。例えば、ソースレジスタの属性は(bootstrap/application properties sources)、異なる符号化された動き活性化profileに対応しますenvironment

最近では、プロジェクトは、別の環境に応じてLinux/Windows異なるSDKのパラメータをロードします。

カスタムCondition実現

修正することにより、極めて多構成アイテムのためにConfigurationPropertiesビーンのカスタムを@Conditional

public class LinuxCondition  implements Condition{
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String property = context.getEnvironment().getProperty("os.name");
            ...
        return  property.contains("linux");
    }
}复制代码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({LinuxCondition.class})
public @interface ConditionOnLinux {}复制代码

SDKはので、この道をあきらめ荒らしずに、あまりにも多く、スプリットを抽出するために合理的な設計構成クラスではありませんので、

カスタムApplicationContextInitializerは達成します

文脈によると、ロード・resourceディレクトリ、異なる環境プロファイル

public class SelectApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext context) {
        ConfigurableEnvironment env = context.getEnvironment();
        MutablePropertySources mps = env.getPropertySources();

        String property = env.getProperty("os.name");

        if (property.contains("Mac OS X")) {
            mps.addLast(new ResourcePropertySource(new ClassPathResource("linux.properties")));
        } else {
            mps.addLast(new ResourcePropertySource(new ClassPathResource("window.properties")));
        }

    }
}复制代码

問題:初期化2回実行

関連する機能抽出starterモノマーの実行Spring Boot項目を追加する場合はSpring Cloud Context、コードを二回前出を実行します


SpringApplication.run

  • ブレークポイントでマークされたSpringApplicationのrunメソッドでは、問題の殺人者を識別するために。

BootstrapApplicationListener

フォローするすべての方法BootstrapApplicationListener.bootstrapServiceContextの方法を。

我々は見てbootstrapServiceContextの方法、

SpringApplicationBuilder builder = (new SpringApplicationBuilder(new Class[0])).profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF).environment(bootstrapEnvironment).registerShutdownHook(false).logStartupInfo(false).web(WebApplicationType.NONE);
SpringApplication builderApplication = builder.application();
if (builderApplication.getMainApplicationClass() == null) {
    builder.main(application.getMainApplicationClass());
}

if (environment.getPropertySources().contains("refreshArgs")) {
    builderApplication.setListeners(this.filterListeners(builderApplication.getListeners()));
}

builder.sources(new Class[]{BootstrapImportSelectorConfiguration.class});
ConfigurableApplicationContext context = builder.run(new String[0]);
context.setId("bootstrap");复制代码

真実の警告

BootstrapApplicationListener、の使用SpringApplicationBuilderであるが行われ、再起動、Run二回が、最初に起動しないように容器は、そうそこにいるBean二回ロードされた、またはコンテナの実行Tomcatポートの競合を。

画像

おすすめ

転載: juejin.im/post/5dddb88e5188256eaa0ebd08