1

SpringベースのWebアプリケーションでは、暗号化された値をプロパティファイルに保存する必要があります。この目的のために、Springの「PropertyPlaceholderConfigurer」クラスをサブクラス化し、その「convertProperties」メソッドをオーバーライドして、ファイルからプロパティをロードした後、暗号化されたプロパティを復号化するようにしました。これはうまくいきます。

現在、このPPCは、暗号化/復号化の役割を処理するSpringコンテキストの別のBeanに依存しています。現在、このBeanは、SpringコンテキストXMLファイルで「ハードコードされた」値で構成する必要があります。これらの値をPPCを介してプロパティファイルから取得したかったのですが、そうすると循環依存関係が作成されます(復号化機能は、その仕事をするために復号化機能を必要とするPPCから情報を受信できません...)。

だから...私がやろうと思ったのは、2つのプロパティファイルを作成することです。1つは暗号化されたもの用で、もう1つはクリアテキスト用のものです。次に、2つのPPCを作成します。1つは通常のPPCで、もう1つは暗号化されたコンテンツを処理するためのサブクラス化されたデザインです。そうすれば、復号化機能の構成オプションをクリアテキストのプロパティファイルに入れることができます。

残念ながら、Springによってアイテムが初期化される順序に問題があるようです。XMLでのセットアップの例を次に示します。

<bean id="clearTextPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="location" value="clear.properties" />
</bean>

<bean id="encryptedPlaceholder" class="com.mycompany.EncryptedPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="location" value="encrypted.properties" />
    <property name="encryption" ref="encrypter" />
</bean>

<bean id="encrypter" class="com.mycompany.Encrypter">
    <property name="someOption" value="${plain-text-property}" />
</bean>

したがって、この場合、Springで最初に「clearTextPlaceholder」Beanを初期化する必要があります。次に、読み込んだプロパティを使用して、「encrypter」Beanを初期化します。そして最後に、それを使用して、コンテキスト内の他のすべてのアイテムで使用できるように「encryptedPlaceholder」Beanを初期化します。

ただし、実際に発生するのは、起動時に「encrypter」Beanにリテラルの「$ {plain-text-property}」文字列が渡され、その後、両方のPPCが初期化されます(または、不適切に構成された暗号化Bean)。

関連するBeanに「depends-on」属性を追加して初期化順序を強制しようとしましたが、役に立ちませんでした。Springは先に進んで、定義されたすべてのPPCを一度に作成したいと考えているようです。一方は別のBeanに依存しているため、両方がもう一方のBeanが初期化されるまで待機する必要があります。

それは理にかなっていますか?これを機能させるためにここでできることはありますか(コンテキストアウェアなもので雑草に陥る以外に)、それともこれはSpringの制限にすぎませんか?そして、私がそれに取り組んでいる間、私が見ていないこれについて行くためのより良い方法はありますか?

ありがとう、

ダグ

4

1 に答える 1

2

私はあなたの状況を再現しました - はい、あなたが説明したとおりに動作します。PropertyPlaceHolderConfigurers は両方とも BeanPostProcessors です。起動時に、Spring はすべての BeanPostProcessor Bean を作成します。次に、それらを呼び出します。プロパティを設定することで、呼び出しの順序を変更できorderます。ただし、プロセッサを起動する前に、優先順位が最も低いものであっても、常にすべてのプロセッサの作成を終了します。

encrypterBeanの参照を に追加することで、この初期段階encryptedPlaceHolderに移行しました。プロセッサが呼び出される前、つまり、プロパティが解決される前に発生する BeanPostProcessor 作成フェーズ中に作成されます。encrypterencrypter

私が見る限り、別の PropertyPlaceHolderConfigurer の依存関係である Bean のプロパティを PropertyPlaceHolderConfigurer に処理させることはできません。

そして、私がそれに取り組んでいる間、私が見ていないこれについてもっと良い方法はありますか?

[アップデート]

解決策の 1 つはencrypter、プロパティ ファイルを直接読み取れるようにすることです。より「依存性注入に適した」方法は、カスタム ファクトリ Bean を作成することです。参照については、http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-class-instance-factory-methodを参照してください。

<bean id="encrypter" factory-bean="encrypterFactory" factory-method="createInstance">
</bean>

<bean id="encrypterFactory" class="com.mycompany.EncrypterFactory" init-method="init">
   <property name="location" value="clear.properties"/>
</bean>

ファクトリ Bean は次のようになります。

public class EncrypterFactory
{
   Properties properties;
   File file;

   public void setLocation(String fileName)
   {
      this.file = new File(fileName);
   }
   public void init() throws IOException
   {
      properties = new Properties();
      properties.load(new FileReader(file));
   }

   public Encrypter createInstance()
   {
      Encrypter encrypter = new Encrypter();
      encrypter.setSomeOption(properties.getProperty("plain-text-property"));
      return encrypter;
   }
}

新しい特殊目的のファクトリー Bean を作成する必要がありますが、既存の暗号化クラスを変更する必要はありません。

于 2012-12-14T03:38:59.063 に答える