gpt4 book ai didi

spring - 自定义 spring 属性源无法解析 @Value 中的占位符

转载 作者:行者123 更新时间:2023-12-03 00:01:08 24 4
gpt4 key购买 nike

我正在尝试构建一个 Spring 3.1 PropertySource,它从 Zookeeper 节点读取其值。为了连接到 Zookeeper,我使用 Curator来自 Netflix。

为此,我构建了一个自定义属性源,它从 Zookeeper 读取属性值并返回它。当我像这样解析属性时,这工作得很好

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

但是,当我尝试实例化一个带有 @Value 注释字段的 bean 时,就会失败:

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

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

这个问题很可能与 Zookeeper 无关,而是与我注册属性源和创建 bean 的方式有关。

任何见解都将受到高度赞赏。

更新1:

我正在从 XML 文件创建应用程序上下文,如下所示:

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 结合使用)时,这似乎有效。为什么它不能与 ClassPathXmlApplicationContext 一起使用?

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

最佳答案

回答您的更新 2: 这不适用于您的原始配置(使用 @PostConstruct 注册 PropertySource),因为 PropertySource 注册得很晚,此时当你的目标 bean 已经被构造和初始化时。

通常,占位符的注入(inject)是通过 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);
}
}

关于spring - 自定义 spring 属性源无法解析 @Value 中的占位符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11925952/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com