春の環境抽象化

Environment春はアプリケーション環境の抽象コンテナは二つの重要な要因であるです。彼らは以下の通りですProfilesproperties

Profileビーン定義は、名前の論理的なグループです。複数の容器であってもよいProfileが、指定する必要があるprofileだけこのProfileコンテナにビーンで定義された登録パケットを。豆をに割り当てることのできるXMLまたは注釈で定義されているかどうかProfileEnvironmentオブジェクトのProfile関係が決定することですProfiles(if any)何を、現在アクティブなProfilesデフォルトで有効である必要があり、次の(もしあれば)。

Propertiesほとんどすべてのアプリケーションでは、それは重要な役割を果たしてきた、とさまざまなソースから来ることができます:properties 文件JVM系统属性系统环境变量JNDIServlet Context 参数ad-hoc Properties 对象Mapなどなど。Environmentそして、Propertiesの関係は、彼らから、ソースと解析プロパティの属性を設定するための便利なサービス・ユーザー・インターフェースを提供することです。

1、ビーンは、プロファイルを定義しました

Beanが定義Profiles異なるビーンは異なる環境に登録可能コアコンテナのためのメカニズムを。environment単語がユーザーごとに異なるものを意味し、この機能は、以下を含む多くの状況で非常に便利です。

  • 開発環境でのデータソースを使用して、メモリ、QAまたは本番環境を使用してJNDIからデータソース
  • アプリケーションは、環境性能に配備されているのみだけ登録した監視インフラストラクチャ
  • クライアントや顧客のためにカスタマイズされたB登録Bean実装を展開します

それが必要とする、私たちは最初のユースケースでの実用化を考えてみましょうDataSource次のようにテスト環境では、構成であってもよいです。

@Bean
public DataSource dataSource() {
    return new EmbeddedDatabaseBuilder()
        .setType(EmbeddedDatabaseType.HSQL)
        .addScript("my-schema.sql")
        .addScript("my-test-data.sql")
        .build();
}

私たちは今、アプリケーションがJNDIデータソースカタログ本番アプリケーション・サーバに登録されることを想定し、QAまたは本番環境に、このアプリケーションをデプロイする方法を考えてみましょう。私たちはdataSource今、このようになります豆:

@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
    Context ctx = new InitialContext();
    return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}

問題は、現在の環境で、どのようにこれら二つの変数の間で切り替えるようにスイッチするということです。時間が経つにつれて、春のユーザーは、このタスクを達成するために多くの方法を考案しました。一般的には、システム環境変数に依存しあって${placeholder}[占位符]XMLの<import />組み合わせコード断片。環境変数に応じて正しい値に分析プロファイルパス。Bean定義Profiles、それはこの問題に対する解決策を提供し、コンテナのコア機能です。

@プロフィール

@Profileコンポーネントのアノテーションを使用すると、1つまたは複数の指定の登録を宣言することを可能にするProfile内部を。上記の例を使用して、我々は、書き換え可能
dataSourceな構成を次のようになります。

@Configuration
@Profile("dev")
public class StandaloneDataConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:com/bank/config/sql/schema.sql")
            .addScript("classpath:com/bank/config/sql/test-data.sql")
            .build();
    }
}
@Configuration
@Profile("production")
public class JndiDataConfig {
    @Bean(destroyMethod="")
    public DataSource dataSource() throws Exception {
        Context ctx = new InitialContext();
        return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
    }
}

@profileメタアノテーションとして使用することができ、目的は、カスタムの組み合わせのコメントを作成することです。次の例では、カスタム定義され@Productionた注釈を、代わりに使用することができます@Profile("production")

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("production")
public @interface Production {
}

@profileまた、この方法のアップが1つの特定のコンフィグレーションBeanが含まれて宣言することができます。

@Configuration
public class AppConfig {
    @Bean
    @Profile("dev")
    public DataSource devDataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:com/bank/config/sql/schema.sql")
            .addScript("classpath:com/bank/config/sql/test-data.sql")
            .build();
    }
    @Bean
    @Profile("production")
    public DataSource productionDataSource() throws Exception {
        Context ctx = new InitialContext();
        return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
    }
}

XMLビーン定義プロファイル

対応するラベルは、XML内にあるprofile要素。上記の設定例では、2つのXMLファイルで上書きすることができます。

<beans profile="development"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="...">

    <jdbc:embedded-database id="dataSource">
        <jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>
        <jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>
    </jdbc:embedded-database>
</beans>
<beans profile="production"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="...">

    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
</beans>

また、別のファイルで定義された回避は同じファイルに入れ子にすることができます<beans />レーベル:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="...">

    <!-- other bean definitions -->

    <beans profile="development">
        <jdbc:embedded-database id="dataSource">
            <jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>
            <jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>
        </jdbc:embedded-database>
    </beans>

    <beans profile="production">
        <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
    </beans>
</beans>

spring-bean.xsd一つ以上の許可<beans />ような要素が、<beans />唯一の要素と他の<beans />要素と同じレベル。
これは、XMLファイル内の混乱を引き起こすことなく、柔軟性を提供するのに役立つはずです。

豆の法的定義

<beans>
    <beans profile="development">
        ...
    </beans>
    <beans profile="production">
        ...
    </beans>
</beans>

違法ビーンの定義

<beans>
    <bean />
    <beans profile="development">
        ...
    </beans>
    <bean />
</beans>

活性化プロフィール

今、私たちは、コンフィギュレーションを更新したことを、我々はまだ春に指示する必要がProfile効果的であるが。私たちは今、私たちのサンプルアプリケーションを起動した場合、我々は、スロー表示されますNoSuchBeanDefinitionExceptionコンテナと呼ばれる、見つけることができないので、例外をdataSourceのSpring Bean。

これは、いくつかの方法によって活性化することができるProfileが、最も直接的な方法は、プログラムにあるApplicationContext内部のEnvironment APIプログラミング:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("development");
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
ctx.refresh();

また、Profileそれはまた、可能spring.profile.active宣言起動します。システム環境変数、JVMシステムプロパティでweb.xmlのServletContextパラメータ
にもエントリ(第2節「PropertySource抽象化」)JNDI。統合ではで、テストspring-testモジュール@activeprofilesアクティブ注釈へprofile

ノート、してくださいProfileいない「非そのため、ある」命題、同時に複数起動することができるProfileの。あなたが呼び出すことによって、方法をプログラムすることができるsetActiveProfiles()プロフィールの複数の活性化方法。可変のパラメータ文字列を受信する方法(String…)

ctx.getEnvironment().setActiveProfiles("profile1", "profile2");

することができますspring.profiles.activeあなたは、カンマ区切り受け取ることができる、宣言することがprofile名前のリストを:

-Dspring.profiles.active="profile1,profile2"

デフォルトのプロフィール

通常の状況下で、我々は設定されていないBeanを定義するprofileことで、ヘルプたち春のデフォルト設定、profiledefault

@Configuration
@Profile("default")
public class DefaultDataConfig {

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:com/bank/config/sql/schema.sql")
            .build();
    }
}

いない場合はProfile起動し、それは上記を作成しますdataSource。これは、一つ以上のBeanとして定義されたデフォルトを提供する方法として見ることができます。他が有効になっている場合はprofile、デフォルトではprofile適用されません。

通したりすることにより、デフォルトの属性変更の名前を。EnvironmentsetDefaultProfiles()spring.profiles.defaultprofile

2、PropertySource抽象化

SpringのEnvironment抽象は、構成階層の元の属性の検索操作を提供します。完全に説明するために、次の例を考えてみます。

ApplicationContext ctx = new GenericApplicationContext();
Environment env = ctx.getEnvironment();
boolean containsFoo = env.containsProperty("foo");
System.out.println("Does my environment contain the 'foo' property? " + containsFoo);

上記のコードでは、我々は、高レベル問い合わせ春の道を参照して、そのfoo属性は、現在の環境として定義されます。この質問に答えるために、EnvironmentオブジェクトがセットになりますPropertySource検索するオブジェクトを。PropertySourceこれは、任意の源であるkey-value(键-值)のシンプルな抽象.Spring StandardEnvironment2つのオブジェクト構成PropertySourceJVMシステムプロパティ変数の1( -オブジェクト通过 system.getproperties() 获取)、別のシステム環境変数の代わりに(通过 system.getenv() 获取)

これらのデフォルト属性は、ソースに存在しStandardEnvironmen、別のアプリケーションインチ StandardServletEnvironmentそれはを含むソースの追加のデフォルトのプロパティが含まservlet配置とをservlet上下文参数同様に、StandardPortletEnvironmentあなたもアクセスできるportlet構成とし、portlet上下文参数財産ソースとして。どちらも、選択的に有効にすることができますJndiPropertySource詳細については、を参照してくださいjavadocs

具体的には、使用中にStandardEnvironment、システムは、システムのプロパティ変数またはシステム環境変数が含まれている実行されている場合はfoo、プロパティを、その後の呼び出しがenv.containsProperty("foo")返されますtrue

検索プロパティは、階層構造を持っています。デフォルトでは、システムプロパティはそうならば、環境変数よりも優先されますfooプロパティはに起こったenv.getproperty(“foo”)、セットコール、システムプロパティの値が「勝利」とは、環境変数に戻るに優先権を与えます。プロパティの値がマージされていませんが、完全に前のエントリを覆われていることをしてくださいノート。

共通のためStandardServletEnvironment、完全な階層が優先度がトップダウンで、次のとおりです。

  • (例えば、コンテキストのDispatcherServletで)のServletConfigパラメータ
  • ServletContextパラメータ(web.xmlのラベル)
  • JNDI環境変数(「で、java:comp / env /」词目)
  • JVMシステムプロパティ(「-D」コマンドラインパラメータ)
  • JVMシステム環境(システム環境変数)

最も重要なのは、全体のメカニズムが設定可能です。たぶん、あなたは検索にそれらを統合することを期待して、カスタム属性のソースを持っています。これは問題ありません-単に実装されており、自身のインスタンス化PropertySourceし、現在に追加EnvironmentPropertySourceコレクション:

ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new MyPropertySource());

上記のコードでは、MyPropertySource検索で最高の優先順位を添加します。それが含まれている場合fooの特性を、それが他のどのになりますPropertySource任意のされfoo検出され、前のプロパティに戻ります。MutablePropertySources API多くの方法が開示され、これらの方法は、ソースの特性の組の正確な操作を可能にします。

3、@ PropertySource

@PropertySource注意事項は、宣言するための便利な機構を提供するPropertySource春に追加Environmentです。

キー/値ペアが与えられtestbean.name=myTestBeanた文書をapp.properties。次@configurationのクラスが使用Springコンテキストにロードを内部。その後、呼び出しが返されます@propertysourceapp.propertiesEnvironmentestBean.getName()myTestBean

@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {

    @Autowired
    Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(env.getProperty("testbean.name"));
        return testBean;
    }
}

@propertysourceリソースパス位置を添加することができる${...}プレースホルダ。これは、環境に登録されているソースの性質に応じて解決されます。例えば:

@Configuration
@PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
public class AppConfig {

    @Autowired
    Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(env.getProperty("testbean.name"));
        return testBean;
    }
}

仮定するmy.placeholderようなシステムプロパティまたはシステム環境変数のプレースホルダとしてすでにソースに登録されているプロパティに存在するが、適切な値に解決されます。そうでない場合には、default/pathそれがデフォルトとして使用されます。デフォルト値を指定して、いないプロパティを解決できない場合は、それがスローされますIllegalArgumentException例外を。

Javaでは8つのプロパティの@propertysource注釈は反復可能です。しかし、すべてのこれらの@propertysourceいずれの構成クラスで、直接メタアノテーションと同じカスタム注釈に:ノートは、同じレベルで宣言する必要があります。直接のコメントは、元のノートをカバーしますので、直接コメントや混合のメタアノテーションは、推奨されません。

4、書類上のプレースホルダの解決

過去には、プレースホルダ要素の値は、JVMシステム属性または環境変数によって解決することができます。これはもはやケースです。環境抽象化が容器全体で統合されているので、プレースホルダを解析することによってそれを解決するのは簡単です。適切な時期に独自の属性のソースを追加し、システムプロパティと環境変数の優先順位によって検索を変更、または完全に削除:あなたが好きなように解決プロセスを構成することができますことをこれが意味。

どのような具体的には、関係なく、ユーザー定義属性の、環境で使用可能な限り、次の文が動作することができます:

<beans>
    <import resource="com/bank/service/${customer}-config.xml"/>
</beans>

オリジナル住所:

公開された173元の記事 ウォンの賞賛221 ビュー700 000 +

おすすめ

転載: blog.csdn.net/u012410733/article/details/81393683