2012-08-12 3 views
5

でプレースホルダを解決しません。飼育係に接続するために私はNetflixのからCuratorを使用しています。私は飼育係からプロパティの値を読み取り、それを返すカスタムプロパティのソースを構築したことについてはカスタムバネ性の源は、私が飼育係・ノードからその値を読み取り春3.1 PropertySourceを構築しようとしている@value

。この問題はあり

​​

:私はこれが失敗した後、@value注釈付きフィールドを持つBeanをインスタンス化しようとすると、私は、しかし、この

ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient); 
ctx.getEnvironment().getPropertySources().addLast(zkPropertySource); 
ctx.getEnvironment().getProperty("foo"); // returns 'from zookeeper' 

のようなプロパティを解決していたときにこれが正常に動作しますほとんどの場合、動物園の係員とは関係ありませんが、私は財産源を登録して豆を作ります。

任意の洞察力を高く評価されています。

アップデート1:

私はこのようなXMLファイルからアプリのコンテキストを作成しています:

public class Main { 
    public static void main(String[] args) throws Exception { 
     ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 
     ctx.registerShutdownHook(); 
    } 
} 

飼育係に接続しているクラスが@Componentです。

@Component 
public class Server { 
    CuratorFramework zkClient; 

    public void connectToZookeeper() { 
     zkClient = ... (curator magic) ... 
    } 

    public void registerPropertySource() { 
     ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient); 
     ctx.getEnvironment().getPropertySources().addLast(zkPropertySource); 
     ctx.getEnvironment().getProperty("foo"); // returns 'from zookeeper' 
    } 

    @PostConstruct 
    public void start() { 
     connectToZookeeper(); 
     registerPropertySource(); 
     MyBean b = ctx.getBean(MyBean.class); 
    } 
} 

アップデート2

これは私がAnnotationConfigApplicationContextとの組み合わせでXMLレスの構成、すなわち@Configuration、@ComponentScanと@PropertySourceを使用していたときに動作するようです。なぜClassPathXmlApplicationContextで動作しないのですか?あなたのアップデート2に答える

@Configuration 
@ComponentScan("com.goleft") 
@PropertySource({"classpath:config.properties","classpath:version.properties"}) 
public class AppConfig { 
    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 

答えて

4

:PropertySourceがターゲットBeanがすでに構築されているこの時点で、非常に遅れが登録されているので、これはあなたの元の設定(@PostConstructを使用してPropertySourceを登録する)では動作しませんと初期化されました。

通常、プレースホルダの挿入は、Springライフサイクルの非常に早い(この段階でBeanは作成されていません)BeanFactoryPostProcessorを介して行われ、PropertySourceがその段階で登録されている場合はプレースホルダを解決する必要があります。

しかし最善のアプローチはApplicationContextInitializerを使用することで、ApplicationContextの上のハンドルを取得し、そこpropertySourceを登録するには:

public class CustomInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> { 
    public void initialize(ConfigurableWebApplicationContext ctx) { 
     ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient); 
     ctx.getEnvironment().getPropertySources().addFirst(zkPropertySource); 
    } 
} 
+0

を、あなたのアップデートでものAppConfigコードが含まれてくださいすることができます。 –

+0

私は問題を単純化しましたが、今はもう動作しません。常にconfigファイルからロードされます。まあ、実際にそれは私の非単純化されたプロジェクトだけのAppConfigクラスを持つとプロパティがconfig.propertiesファイルに存在しないで作業を行います。非WebアプリケーションでApplicationContextInitializerを使用するにはどうすればよいですか? – magiconair

+1

はい、そうです、少し違っています。私は注釈とXMLベースのアプリケーションコンテキストのために一貫して動作するテストを使用して、リポジトリにプルリクエストを送ってきました。 –

関連する問題