2012-04-02 4 views
6

春は設定の目的のためのSpring Beanへなど、タイムアウトなどの値を注入するための素敵なメカニズムPropertyPlaceholderConfigurer、JDBC URLを持っています。実行時に変更される構成値を処理する賢明な方法はありますか?春は:透明ランタイム変更可能プロパティの設定を行う方法

UPDATE:春3.1でPropertySource Sを介してデータベースなどの非静的な設定ソースを含めるための良い方法があります。一部のApplicationContextでは、原則的に構成値の変更を処理できるリフレッシュ・メカニズムが提供されています。ただし、アプリケーションを最初に停止してから、すべてのBeanを新しく作成して、アプリケーション・コンテキストを再開します。しかし、私たちの目的のためには、サーバーが現在実行中の要求を正しく処理するように、これを透過的に行う方法が必要です。

これを行う別のアイデアは、設定が変更されたときに新しいオブジェクトを作成するカスタムスコープです。あいにくスコープに提供されるObjectFactoryは、プレースホルダがコンフィグレーションから新たに読み込まれないように、前処理されたBean定義を使用します。したがって、作成されたオブジェクトは同じ構成を持ちます。 :-(

+0

おそらく、それを行う方法は、PropertyOverrideConfigurer http://stackoverflow.com/a/595201/21499を使用することですが、プロパティのオーバーライドの仕組みは使いにくく、エラーが発生しやすいと思います。 –

答えて

2

次は少し奇妙ですが動作します。 reconfigurableという名前のcustom scopeを作成すると、構成の更新が発生するたびに、そのスコープで作成されたすべてのBeanがスローされます。したがって、設定変更後に新しいBeanが作成されます。

通常の$ {}構文とPropertyOverrideConfigurerの両方の値がBeanDefinitionで永続的に固定されているように見えるため、実際の構成値はスプリング式言語で取得する必要があります。スコーププロキシこのBeanを使用する豆は、常にカスタム範囲から新鮮構成された豆を取り出すよう:あなたは、AOPを使用する必要が

<bean class="blablu.Testbean" scope="reconfigurable" 
    p:someProperty="#{ config['configexplicit']}"> 
    <aop:scoped-proxy /> 
</bean> 

:再構成可能なプロパティsomePropertyを持つBeanのBean宣言は次のようになります。

@Valueでプロパティを宣言することもできます。あなたがコンポーネントのスキャンを使用する場合は、あなたが細部の世話をした場合、注釈

@Scope(value="reconfigurableScope", proxyMode=ScopedProxyMode.TARGET_CLASS) 

とスコープを宣言する必要があります:

public class ReconfigurableScope implements Scope { 

    private final Map<String, Object> nameToObjectMap = new ConcurrentHashMap<String, Object>(); 

    public Object get(final String name, final ObjectFactory<?> objectFactory) { 
     Object bean = nameToObjectMap.get(name); 
     if (null == bean) { 
      bean = objectFactory.getObject(); 
      nameToObjectMap.put(name, bean); 
     } 
     return bean; 
    } 

    // called from outside on each configuration change 
    public void update(final ConfigurationObservable observable, final Object arg) { 
     nameToObjectMap.clear(); 
    } 

} 

プラスいくつかのスレッドの安全性とクリーンアップのもの:スコープの基本的な考え方は次のとおりです。削除されたBeanは、少し後で、アプリケーションコンテキストの終了時に破棄する必要があります。

+0

カスタムスコープのソースコードサンプルはありますか? :) – Kakawait

2

残念ながらpropertiesファイルからの設定は静的であり、私は一般的に経由で動的属性を公開しているやって起動時に起こる:

<context:mbean-export/> 

へ:

@ManagedResource 
@Service 
public class BusinessService { 

    @ManagedAttribute 
    private int age; 

    public int getAge() { 
     return age; 
    } 

    public void setAge(int age) { 
     this.age = age; 
    } 

    public void businessMethod() { 
     //use age... 
    } 

} 

を追加することを忘れないでください。 。あなたの構成は今、あなたはアクセスしjconsoleまたはその他のJMXクライアントを経由して、その属性を変更することができます参照:。。23.3.2 Using Source-Level Metadata (JDK 5.0 annotations)

+0

プロパティファイルは必ずしも静的ではありません。ファイルシステムのどこかに存在し、opsによって変更される可能性があります。あなたは正しい:設定値を更新するために他のメカニズムを使うことができるが、私は素晴らしいSpringプレースホルダメカニズムを使いたい。さもなければ - あなたはどのように多くのグルーコードなしでWebserviceTemplateのタイムアウトを更新しますか? –

+0

@hstoerr:wrt 'WebserviceTemplate' - 何かリフレッシュする必要がない場合でも、いくつかのグルーコードが必要です:http://onebyteatatime.wordpress.com/2009/03/19/how-to-set-socket-timeout -using-spring-webservicetemplate /およびhttp://stackoverflow.com/questions/6733744 –

0

実行時の再構成を効果的に行うには、SpringのCloud Configプロジェクトを使用できます。この構成では、Configuration Repository、つまり設定値を含むgitリポジトリがあります。その後、Configuration Serverをそのリポジトリの前に置きます。このサーバーは、バッキングリポジトリにプッシュが発生するたびに更新されます。最後に、あなたのアプリはそのクライアントのConfig Serverであり、そこから新しい設定を取得します。詳細については、Spring Cloudをご確認ください。

1

あなたがここに達成しようとしているものの実行されている例があります:https://github.com/ldojo/spring-cloud-config-examples

それは春のクラウド構成サーバーとクライアントサービスは、春の雲のバスを介して通信することができ、クライアントの構成プロパティを変更することができます方法を示しています実行時に、構成サーバーのリポジトリーに構成の変更があるとき。

関連する問題