mag*_*air 6 spring properties apache-zookeeper
我正在尝试构建一个Spring 3.1 PropertySource,它从Zookeeper节点读取它的值.为了连接到Zookeeper我正在使用Netflix的Curator.
为此,我构建了一个自定义属性源,它从Zookeeper读取属性的值并返回它.当我解析这样的属性时,这很好用
ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient);
ctx.getEnvironment().getPropertySources().addLast(zkPropertySource);
ctx.getEnvironment().getProperty("foo"); // returns 'from zookeeper'
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试实例化一个带有@Value注释的字段的bean时,这会失败:
@Component
public class MyBean {
@Value("${foo}") public String foo;
}
MyBean b = ctx.getBean(MyBean.class); // fails with BeanCreationException
Run Code Online (Sandbox Code Playgroud)
这个问题很可能与Zookeeper没有任何关系,但是我正在注册属性源并创建bean.
任何见解都受到高度赞赏.
更新1:
我正在从这样的XML文件创建应用程序上下文:
public class Main {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.registerShutdownHook();
}
}
Run Code Online (Sandbox Code Playgroud)
连接到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);
}
}
Run Code Online (Sandbox Code Playgroud)
更新2
当我使用无XML配置时,这似乎有效,即@Configuration,@ ComponentScan和@PropertySource与AnnotationConfigApplicationContext结合使用.为什么它不能用于ClassPathXmlApplicationContext?
@Configuration
@ComponentScan("com.goleft")
@PropertySource({"classpath:config.properties","classpath:version.properties"})
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Run Code Online (Sandbox Code Playgroud)
回答您的更新 2:这不适用于您的原始配置(使用 注册 PropertySource @PostConstruct),因为 PropertySource 注册得很晚,此时您的目标 bean 已经构建和初始化。
通常,占位符的注入是通过BeanFactoryPostProcessor发生的,它在 Spring 生命周期的早期(此时尚未创建 bean),如果在该阶段注册了 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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4942 次 |
| 最近记录: |