Sto provando a creare un PropertySource di Spring 3.1 che legge i suoi valori dai nodi Zookeeper. Per il collegamento a Zookeeper sto usando Curator da Netflix.L'origine della proprietà Spring personalizzata non risolve i segnaposto in @Value
Per questo ho creato una fonte di proprietà personalizzata che legge il valore di una proprietà da Zookeeper e lo restituisce. Questo funziona bene quando sto risolvendo la proprietà come questa
ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient);
ctx.getEnvironment().getPropertySources().addLast(zkPropertySource);
ctx.getEnvironment().getProperty("foo"); // returns 'from zookeeper'
Tuttavia, quando cerco di istanziare un fagiolo che ha un campo con un'annotazione @Value allora questo non riesce:
@Component
public class MyBean {
@Value("${foo}") public String foo;
}
MyBean b = ctx.getBean(MyBean.class); // fails with BeanCreationException
Questo problema ha molto probabilmente non ha nulla a che fare con Zookeeper ma con il modo in cui sto registrando i sorgenti delle proprietà e creando i bean.
Qualsiasi intuizione è molto apprezzata.
Update 1:
che sto creando il contesto applicazione da un file XML in questo modo:
public class Main {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.registerShutdownHook();
}
}
La classe che si collega a Zookeeper è un @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);
}
}
Update 2
Questo sembra funzionare quando sto usando configurazione XML-meno, vale a dire @Configuration, @ComponentScan e @PropertySource in combinazione con un AnnotationConfigApplicationContext. Perché non funziona con ClassPathXmlApplicationContext?
@Configuration
@ComponentScan("com.goleft")
@PropertySource({"classpath:config.properties","classpath:version.properties"})
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Potete per favore includere il codice AppConfig anche nel vostro aggiornamento. –
Ho semplificato il problema ma ora non riesco più a farlo funzionare. Carica sempre dal file di configurazione. Beh, in realtà funziona nel mio progetto non semplificato ma solo con la classe AppConfig e quando la proprietà non esiste nel file config.properties. Come posso utilizzare ApplicationContextInitializer con un'applicazione non web? – magiconair
Sì, hai ragione, funziona un po 'diverso. Ho inviato una richiesta di estrazione al repository con un test che si comporta in modo coerente per l'annotazione e il contesto dell'applicazione basato su xml. –