Spring custom property source does not allow placeholders in @Value

I am trying to create a Spring 3.1 source that reads its values ​​from Zookeeper nodes. To connect to Zookeeper, I use Curator from Netflix.

To do this, I created my own property source, which reads the value of the property from Zookeeper and returns it. This works fine when I resolve a property like this

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

However, when I try to create an instance of a bean that has a field with @Value annotation, this fails:

@Component
public class MyBean {
    @Value("${foo}") public String foo;
}

MyBean b = ctx.getBean(MyBean.class); // fails with BeanCreationException

This problem, most likely, has nothing to do with Zookeeper, but with the way I register property sources and create beans.

Any insight is greatly appreciated.

Update 1:

I create an application context from an XML file as follows:

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

, Zookeeper, @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

, XML, .. @Configuration, @ComponentScan @PropertySource AnnotationConfigApplicationContext. ClassPamlApplicationContext?

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

2:. ( PropertySource @PostConstruct), PropertySource , bean .

BeanFactoryPostProcessor, Spring (beans ), 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);
    }
}
+4

All Articles