4

Spring3.1アプリケーションがあります。次の内容のXMLがあるとします。

<context:property-placeholder location="classpath:somename.properties" />

<context:property-placeholder location="classpath:xxx.properties" />

some.propertiesを常にロードしたいのですが(存在すると仮定します)、2番目のプレースホルダーのxxx部分は、アクティブなプロファイルに応じて何らかの名前に置き換えられます。私はこれで試しました:

<beans profile="xx1">
    <context:property-placeholder location="classpath:xx1.properties" />
</beans>

<beans profile="xx2">
    <context:property-placeholder location="classpath:xx2.properties" />
</beans>

また、両方のファイルには、同じキーで値が異なるプロパティがあります。

しかし、キーがxx1.properties(およびxx2.properties)で定義されている1つのプロパティのプレースホルダーを持つ後のBeanとしては機能しなかったため、Springはキーがアプリケーションコンテキストに見つからないと文句を言います。

4

2 に答える 2

9

できるよ:

  <context:property-placeholder location="classpath:${spring.profiles.active}.properties" />

正常に動作しますが、同時に複数のプロファイルを使用する場合はおそらく適応されません。


2つのプロパティプレースホルダーを宣言するときに、最初のプレースホルダーにすべてのアプリケーションキーが含まれていない場合は、2番目のプレースホルダーを使用できるようにunresolvable=trueを無視して属性を配置する必要があります。それがあなたのやりたいことかどうかはわかりませんが、xx1プロファイルとxx2プロファイルの両方を同時にアクティブにしたい場合はそうかもしれません。

このように2つのpropertyplaceholdersを宣言すると、それらが独立し、xx2.propertiesの宣言では、xx1.propertiesの値を再利用できないことに注意してください。


より高度なものが必要な場合は、アプリケーションの起動時にPropertySourcesを登録できます。

web.xml

  <context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.xxx.core.spring.properties.PropertySourcesApplicationContextInitializer</param-value>
  </context-param>

作成するファイル:

public class PropertySourcesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

  private static final Logger LOGGER = LoggerFactory.getLogger(PropertySourcesApplicationContextInitializer.class);

  @Override
  public void initialize(ConfigurableApplicationContext applicationContext) {
    LOGGER.info("Adding some additional property sources");
    String profile = System.getProperty("spring.profiles.active");
    // ... Add property sources according to selected spring profile 
    // (note there already are some property sources registered, system properties etc)
    applicationContext.getEnvironment().getPropertySources().addLast(myPropertySource);
  }

}

完了したら、コンテキストに追加する必要があります。

<context:property-placeholder/>

スプリングプロパティを処理するのに最適な方法です。ローカルプロパティをどこでも宣言しないため、何が起こっているかをプログラムで制御でき、プロパティソースのxx1値をxx2.propertiesで使用できます。


仕事で私たちはそれを使用していて、それはうまく機能します。3つの追加のプロパティソースを登録します。-インフラストラクチャ:Puppetによって提供されます-プロファイル:プロファイルに従ってロードされた別のプロパティ。-共通:すべてのプロファイルが同じ値を共有する場合など、デフォルトとして値が含まれます。

于 2012-12-25T11:12:00.773 に答える
2

まだ受け付けていないので、提出して回答することにしました。それはあなたが特に探しているものではないかもしれませんが、それは私にとってはうまくいきます。また、新しいアノテーション駆動型構成を使用していますが、xml構成に移植できることにも注意してください。

各環境(dev.properties、test.propertiesなど)のプロパティファイルがあります

次に、すべての構成に使用されるクラスであるRootConfigクラスがあります。このクラスに含まれるのは、@ Configurationと@ComponentScan(basePackageClasses = RootConfig.class)の2つのアノテーションだけです。これは、同じパッケージ内の何かをスキャンするように指示します。

次に、どこにでも座っている私の通常の構成をすべて含む構成があります。上記のルート構成クラスと同じパッケージに、各環境の構成もあります。

環境固有の構成は、環境固有のプロパティファイルを指すために次の注釈が付いた単なるマーカークラスです。

@Configuration
@PropertySource("classpath:dev.properties")
@Import(NormalConfig.class)
@Profile("dev")

インポートは、通常の構成クラスを取り込むように指示します。ただし、そこに入ると、環境固有のプロパティが設定されます。

于 2015-03-01T17:33:23.357 に答える